查询逻辑,需要解决方案建议

时间:2019-02-22 21:33:03

标签: sql postgresql select

http://sqlfiddle.com/#!17/e9c97/59

有我的示例数据库。由WITH创建的表是简化版本,以防万一,如果我在工作,is_paid状态是许多其他条件的集合,因此不能仅从orders表中使用它。但是输出是一样的

我要完成的工作是查找第一个(min(order_id))的订单详细信息,其中所有客户的订单均未付款,或者未付款订单的min(order_id)小于已付款订单的min(order_id)

简单:将未付款订单之前已付款订单的客户从结果中排除。

having min(onp.order_id) < min(op.order_id)这部分是胡扯的,没有在单个customer_id的顺序内进行迭代,但是该怎么做?

我考虑解决方案的时间越长,我尝试的逻辑方法就越少。

预期结果应该是:

order_id, customer_id, amount
3         101          30
5         102          15
11        104          31
15        105          11

1 个答案:

答案 0 :(得分:1)

我猜下面的查询应该可以完成工作:

SELECT * FROM (
    SELECT o.*, 
        MAX(is_paid) OVER(PARTITION BY customer_id ORDER BY order_id) mp, 
        ROW_NUMBER() OVER(PARTITION BY customer_id, is_paid ORDER BY order_id) rn
    FROM orders o
) x WHERE is_paid = 0 AND rn = 1 AND mp = 0

查询使用具有窗口功能的子查询:

  • 检查是否已为该客户支付任何先前订单:MAX(is_paid) OVER(...)
  • 为客户/状态组中的每条记录分配一个序列号:ROW_NUMBER() OVER(...)

如果没有先前的付款订单,并且这是第一笔未付款记录,那么该记录将由外部查询过滤:

Demo on DB Fiddle

| order_id | customer_id | amount |
| -------- | ----------- | ------ |
| 3        | 101         | 30     |
| 5        | 102         | 15     |
| 11       | 104         | 31     |
| 15       | 105         | 11     |