如何在使用order by和limit的子查询上连接表

时间:2014-05-27 17:00:24

标签: sql oracle sqlite

对于匹配给定where子句的表tClass中的每一行,

加入tEv的第一行,按时间排序,其中tEv.class_id = tClass.class_id

以下代码会引发错误 ORA-01799:列可能不是外部连接到子查询

select
    c.class_id,
    c.class_name,
    e.start_time,
    e.ev_id
from
    tClass c 
    left join tEv e on (
        e.ev_id = ( 
            select
             ss1.ev_id 
            from (
                select 
                    ed.ev_id
                from
                    tEvDisp ed,
                    tEv e
                where
                        ed.class_id = c.class_id
                    and ed.viewable = 'Y'
                    and ed.display_until > localtimestamp
                    and e.ev_id = ed.ev_id
                order by
                    e.start_time
                ) ss1
            where
                rownum = 1
            )
        )
where
    c.is_matching = 'Y';

如何重写以完成所描述的内容?

以上是针对oracle,但需要在sqlite中工作(在必要时替换)

2 个答案:

答案 0 :(得分:1)

不知道SQLite - 如果这不起作用则需要单独提出问题 - 但对于Oracle,您可以这样做:

select c.class_id,
  c.class_name,
  e.start_time,
  e.ev_id
from tClass c 
left join (
  select class_id, ev_id, start_time
  from (
    select ed.class_id,
      ed.ev_id,
      e.start_time,
      row_number() over (partition by ed.class_id order by e.start_time) as rn
    from tEvDisp ed
    join tEv e on e.ev_id = ed.ev_id
    where ed.viewable = 'Y'
    and ed.display_until > localtimestamp
  )
  where rn = 1
) e on e.class_id = c.class_id
where c.is_matching = 'Y';

这使用了一个查询最多tEv数据的子查询,使用分析row_number()来标识每个class_id的最新数据,这些数据受rn = 1过滤器的限制。

然后,每个class_id最多包含一行的子查询将用于tClass的左外连接。

答案 1 :(得分:0)

这种结构应该能满足你的需要。你可以修复细节。

select c.classid
, c.classname
, temp.maxstarttime

from tClass c left join (
select c.classid id
max(e.start_time) maxstarttime
from tClass join tEv on tEv.classId = tClass.ClassId
where whatever
group by c.classid) temp on c.classid = temp.id