按左连接表排序

时间:2018-03-13 14:31:53

标签: sql postgresql

我有orders表和order_histories表。我需要按orders排序order_histories.created_at,但只需order_histories state_to = 'submitted' {。}}。

order有多个order_histories,可能没有submitted。它也可能有多个submitted - 在这种情况下我对最后一个感兴趣(因此MAX(order_histories.created_at))。

我想出的是下面的内容。但是,这还不够,因为不包含orders submitted order_history

SELECT orders.*, MAX(order_histories.created_at) AS date
FROM orders
LEFT JOIN order_histories ON order_histories.order_id = orders.id
WHERE order_histories.state_to = 'submitted'
GROUP BY orders.id
ORDER BY date ASC, orders.id DESC

如何使其正确?

2 个答案:

答案 0 :(得分:2)

外连接表的条件属于ON子句中不在WHERE子句中的条件:

SELECT orders.*, MAX(order_histories.created_at) AS date
FROM orders
LEFT JOIN order_histories ON  order_histories.order_id = orders.id
                          AND order_histories.state_to = 'submitted'
GROUP BY orders.id
ORDER BY date ASC NULLS LAST, orders.id DESC;

使用WHERE子句代替渲染您的联接仅仅是内部联接,因为它取消了所有外部连接的行(即那些没有提交订单历史记录的行)。

答案 1 :(得分:2)

通过这种方式,您将获得所有订单

  • 如果存在一个提交状态的订单,则返回其日期
  • 如果您有更多带有州提交的order_histories,则只返回最大日期
  • 如果您的订单没有提交状态,那么该日期将为NULL(LEFT OUTER JOIN的精神)

  • 如果您想在没有提交状态的情况下放弃订单,请指定它,以便我更改查询

试试这个:

SELECT orders.*, 
(SELECT MAX(oh.created_at) 
FROM order_histories oh
WHERE oh.order_id = orders.id
AND oh.state_to = 'submitted') AS date
FROM orders
ORDER BY date ASC, orders.id DESC