Oracle显然不允许对子查询进行外连接。对于表A中的每一行,我正在尝试在表B上找到具有相同ID和最新日期的行。
这样的事情:
SELECT a.*, b.date, b.val1, b.val2
FROM a, b
WHERE b.id (+) = a.id
AND b.date (+) = (SELECT MAX(b.date) FROM a, b WHERE a.id = b.id);
删除b.date上的外连接(+)允许对其进行解析,但是当表B上没有行时不返回任何行。在这种情况下,我需要查询只返回NULL。有办法解决这个问题吗?
由于
答案 0 :(得分:4)
我认为你想要的是:
SELECT a.*, b.date, b.val1, b.val2
FROM a
LEFT JOIN b ON b.id = a.id
WHERE (b.date is null
or b.date = (SELECT MAX(b2.date) FROM b b2 WHERE a.id = b2.id));
这样,外连接只在id
上执行。然后,我们会过滤掉b.date
中max
对应行a
不是a
的所有行。
另外,您会注意到我从子查询中删除了b
。最初编写时,子查询返回a
中max(date)
中具有{{1}}中相应行的最大日期。外部查询的每一行都将使用相同的值。修订版本使子查询与外部查询相关(即,它将为返回的每一行获得相应的{{1}}。
答案 1 :(得分:3)
我已经投票支持Allan的答案,但只是为了演示另一种方法,以下是如何使用分析函数完成的:
SELECT * FROM (
SELECT a.*, b.date, b.val1, b.val2,
ROW_NUMBER() over (PARTITION BY a.id ORDER BY b.date DESC) r
FROM a LEFT JOIN b ON a.id=b.id
)
WHERE r=1
即使有多个a.id
行具有最大日期,每个b
也只会包含一行。要包含所有这些内容,请将ROW_NUMBER
更改为RANK
。
答案 2 :(得分:0)
编辑:您可以将最大日期保存到变量
DECLARE @maxDate as datetime
SET @maxDate = (SELECT MAX(date) FROM b)
SELECT a.*, b.date, b.val1, b.val2
FROM a
LEFT OUTER JOIN b ON a.id = b.id
AND b.date = @maxDate
这可能比Allan的答案更有效或更低效,这取决于A是否有比B更多的行(反之亦然)。如果B有很多行,那么查询它两次(我的答案就是这样)可能不是最佳解决方案。
答案 3 :(得分:0)
标量子查询怎么样?
select a.*, (select max(b.date) from b where b.id = a.id) as b_date
from a;