在条件下获取最大值

Get max value with a condition

如何获取每个 ID 的最大状态? 请注意,如果状态为成功,则必须忽略后面的状态。

示例数据如下:

+-------+------------+---------------------+
|  id   |   status   |     created_at      |
+-------+------------+---------------------+
| 76efg | expired    | 2021-01-07 05:19:03 |
| 76efg | pending    | 2021-01-14 06:55:13 |
| fsf56 | successful | 2021-01-25 11:18:03 |
| ghl56 | successful | 2021-01-08 05:19:03 |
| ghl56 | expired    | 2021-02-02 17:37:10 |
+-------+------------+---------------------+

期望的输出:

+-------+------------+---------------------+
|  id   |   status   |     created_at      |
+-------+------------+---------------------+
| 76efg | pending    | 2021-01-14 06:55:13 |
| fsf56 | successful | 2021-01-25 11:18:03 |
| ghl56 | successful | 2021-01-08 05:19:03 |
+-------+------------+---------------------+

这是一种使用解析函数的方法:

WITH cte AS (
    SELECT *, COUNT(*) FILTER (WHERE status = 'successful') OVER (PARTITION BY id) cnt,
              ROW_NUMBER() OVER (PARTITION BY id ORDER BY created_at DESC) rn
    FROM yourTable
)

SELECT id, status, created_at
FROM cte t1
WHERE
    (rn = 1 AND cnt = 0) OR
    (cnt > 0 AND status = 'successful' AND NOT EXISTS (SELECT 1 FROM cte t2
                                                       WHERE t2.id = t1.id AND
                                                             t2.created_at > t1.created_at AND
                                                             t2.status = 'successful'));

Demo

外部查询中的过滤逻辑在两种情况下保留一条记录:

  1. 给定 id 组的任何记录都没有 successful 状态,在这种情况下,我们采用最新记录,或者
  2. 给定的 id 组有 successful 条记录,在这种情况下,我们采用最近的 successful 条记录。