在LEFT OUTER JOIN表的最后一行中按值过滤

时间:2013-12-29 06:02:39

标签: sql postgresql join aggregate-functions window-functions

我在PostgreSQL(版本9.1.11)中有一个Clients表,我想编写一个查询来过滤该表。该查询应仅返回满足以下条件之一的客户端:

- 客户的最后一个订单(基于orders.created_at)过去有一个fulfill_by_date。

OR

- 客户端根本没有订单

我已经寻找了大约2个月的时间,一个解决方案。

我看过Postgres中的custom last aggregate functions但是无法让它们工作,并且觉得必须有一种内置的方法来实现这一点。

我也查看了Postgres last_value window functions,但大多数示例都是单个表,而不是连接多个表的查询。

任何帮助将不胜感激!以下是我想要的样本:

Clients table:  
| client_id | client_name  |
----------------------------
| 1         | FirstClient  |
| 2         | SecondClient |
| 3         | ThirdClient  |
Orders table:
| order_id | client_id | fulfill_by_date | created_at |
-------------------------------------------------------
| 1        | 1         | 3000-01-01      | 2013-01-01 |
| 2        | 1         | 1999-01-01      | 2013-01-02 |
| 3        | 2         | 1999-01-01      | 2013-01-01 |
| 4        | 2         | 3000-01-01      | 2013-01-02 |
Desired query result:
| client_id | client_name  |
----------------------------
| 1         | FirstClient  |
| 3         | ThirdClient  |

1 个答案:

答案 0 :(得分:2)

以这种方式试试

SELECT c.client_id, c.client_name
  FROM clients c LEFT JOIN
(
  SELECT *, ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY created_at DESC) rnum
    FROM orders
) o 
    ON c.client_id = o.client_id
   AND o.rnum = 1
 WHERE o.fulfill_by_date < CURRENT_DATE
    OR o.order_id IS NULL

输出:

| CLIENT_ID | CLIENT_NAME |
|-----------|-------------|
|         1 | FirstClient |
|         3 | ThirdClient |

这是 SQLFiddle 演示