对于匹配给定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中工作(在必要时替换)
答案 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