如何在外连接条件中使用子查询

时间:2018-01-12 09:51:51

标签: sql oracle join greatest-n-per-group

我的数据库有客户和订单。客户可能有许多订单,其中包含不同的主键和创建日期。

我想为客户提供一个视图,其中包括每个客户使用最新订单加入(如果客户没有任何订单,则为null)。

我尝试了以下

SELECT [...], c.customer_id, o.order_id
FROM customers c
LEFT OUTER JOIN [...]
LEFT OUTER JOIN [...]
[...]
LEFT OUTER JOIN orders o ON (
    o.customer_id = c.customer_id
    AND o.create_dt = (
        SELECT MAX(create_dt) FROM orders o2 WHERE o2.customer_id = c.customer_id
    )
);

但我收到以下错误

  

列可能不是外部连接到子查询

我发现Oracle不支持外连接中的子查询。实现此视图的正确方法是什么?请注意,此示例已简化,对语句的必要更改应仅影响特定连接,因为有多个其他连接和条件正在进行,为简单起见,此处未显示。

3 个答案:

答案 0 :(得分:1)

我使用了以下我自己想出的解决方案

SELECT [...],
c.customer_id,
(select o.order_id from orders where o.customer_id = c.customer_id
    AND o.create_dt = (
        SELECT MAX(create_dt) FROM orders o2 WHERE o2.customer_id = 
          c.customer_id))
as order_id
FROM customers c
LEFT OUTER JOIN [...]
LEFT OUTER JOIN [...]

基本上,这实现了我尝试通过join实现的相同结果。为什么我不能在连接中使用子查询,但在列中我可以吗?使用连接与子查询对列性能明智和其他方面的优缺点是什么?我应该在哪些场景中使用?

我认为我尝试过的联接(它没有用)更能够以声明的方式表达我想要实现的目标,并且甲骨文不支持那里的子查询是一种耻辱。 。这种限制的原因是什么?

答案 1 :(得分:0)

您可以探索outer applycross apply来实现您的目标。片段可能如下所示

select d.*, e.*
from   customers c
outer apply (
    select [...], o.order_id
    from   orders o
    where  o.customer_id= c.customer_id
    order  by create_dt desc
    fetch first 1 rows only 
) e 

有关详细信息,请访问此link

答案 2 :(得分:0)

我会将GROUP BYMAX

结合使用
SELECT c.customer_id, o.order_id
FROM customers c
LEFT OUTER JOIN orders o ON o.customer_id = c.customer_id
LEFT OUTER JOIN (
    SELECT customer_id, MAX(create_dt) max_create
    FROM orders 
    GROUP BY customer_id
) t ON t.customer_id = o.customer_id AND
       t.max_create = o.create_dt