在ON条款

时间:2017-12-05 14:36:51

标签: sql db2

如果这个问题已有答案,请不要抨击我,但我没有找到答案。

基本上我想在ON的{​​{1}}子句中进行子选择,以获得时间范围内的最新条目。

(开始和结束时间是时间戳,硬编码,局部变量或Cobol程序中的主变量)以简化我在该问题中使用的整数。

Left join

现在这不起作用,我收到以下错误:

  

AN ON CLAUSE是无效的。 SQLCODE = -338

因为(see the docs)

  

ON子句不能包含子查询。

现在我们可以做的是围绕它而不是加入Select * from table1 as t1 left join table2 as t2 on t1.primary = t2.secondary and t2.timestamp = ( select max(t2a.timestamp) from table2 as t2a where t2.primary = t2a.primary and t2a.timestamp > starttime and t2a.timestamp < endtime ) 来加入已经分隔的子查询。但这围绕着查询优化器,从根本上杀死了性能:

table2

知道如何解决这个问题吗?

示例数据表1:

Select * from table1 as t1
left join (
    select t2a.secondary from table2 as t2a
        where t2a.timestamp = (
            select max(t2b.timestamp)
            from table2 as t2b
            where t2a.primary = t2b.primary 
            and t2b.timestamp > starttime
            and t2b.timestamp < endtime
        )
    )as t2
on t1.primary = t2.secondary

示例数据表2:

t1.primary 
         1         
         2  
         3       

变量:

t2.primary t2.secondary t2.timestamp
         1            1           4
         2            1           5
         3            1          10
         4            2           4
         5            2           5

预期结果:

starttime = 3
endtime   = 6

2 个答案:

答案 0 :(得分:1)

这应该有效

select *
from table1 t1
left join (
   select t2.primary, t2.secondary, t2.timestamp,
          row_number() over (partition by t2.secondary order by t2.timestamp desc) rn
   from table2 t2
   where t2.timestamp between starttime and endtime
) t on t1.primary = t.secondary and t.rn = 1

如果您有索引table2(timestamp, secondary, primary)或至少table2(timestamp, secondary),那么它应该运行得非常快。如果没有索引,它仍然可以很好地运行,因为它会导致对表进行一次顺序扫描。

答案 1 :(得分:0)

像这样的事情。只是在午餐前输入,所以如果它不起作用,不要打击我。

select * from table1 a left join 
(select t2b.primary, max(t2b.timestamp) mxts
            from table2 t2b
            group by t2b.primary
) as b on a.primary = b.primary
left join table2 on b.primary = table2.secondary and 
table2.timestamp = mxts and table2.timestamp between mystartts and myendts

NOte:不要假设时间戳是唯一的,可以用来从表中提取最后一个条目,因为这会非常脆弱。