2

显然,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。有没有解决的办法?

谢谢

4

4 回答 4

3

我已经投票支持艾伦的答案,但只是为了演示一种替代方法,以下是如何使用分析函数来完成:

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_NUMBERRANK

于 2014-02-26T17:15:05.670 回答
3

我想你想要的是这样的:

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)为返回的每一行获得对应的)。

于 2014-02-26T16:51:42.033 回答
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

这可能比艾伦的答案效率更高或更低,具体取决于 A 的行数是否比 B 多(反之亦然)。如果 B 有很多行,那么查询它两次(我的回答就是这样)可能不是最好的解决方案。

于 2014-02-26T16:43:54.557 回答
0

标量子查询怎么样?

select a.*, (select max(b.date) from b where b.id = a.id) as b_date
from a;
于 2014-02-26T16:46:40.407 回答