PostgreSQL:在ORDER BY之后返回DISTINCT行

时间:2017-05-23 04:45:21

标签: postgresql

我的数据库:

SELECT * FROM odds ORDER BY created_at DESC;

 runner_id | value |         created_at         
-----------+-------+----------------------------
    365910 |     5 | 2017-03-13 14:29:45.404927
    365911 |   2.9 | 2017-03-13 14:29:45.404927
    365912 |     7 | 2017-03-13 14:29:45.404927
    365910 |     5 | 2017-03-13 14:29:02.654532
    365911 |     3 | 2017-03-13 14:29:02.654532
    365912 |     7 | 2017-03-13 14:29:02.654532
    365910 |   5.5 | 2017-03-13 14:28:22.733787
    365911 |     3 | 2017-03-13 14:28:22.733787
    365912 |     7 | 2017-03-13 14:28:22.733787
    365910 |   5.5 | 2017-03-13 14:25:42.885042
    365911 |     3 | 2017-03-13 14:25:42.885042
    365912 |   7.5 | 2017-03-13 14:25:42.885042
    365913 |    10 | 2017-03-13 14:25:42.885042
    365910 |     5 | 2017-03-13 14:25:21.842275
    365911 |     3 | 2017-03-13 14:25:21.842275
    365912 |   7.5 | 2017-03-13 14:25:21.842275
    365913 |    10 | 2017-03-13 14:25:21.842275

我正在寻找具有最高created_at的DISTINCT runner_id行。这是我想要的结果:

 runner_id | value |         created_at         
-----------+-------+----------------------------
    365910 |     5 | 2017-03-13 14:29:45.404927
    365911 |   2.9 | 2017-03-13 14:29:45.404927
    365912 |     7 | 2017-03-13 14:29:45.404927
    365913 |    10 | 2017-03-13 14:25:42.885042

这似乎很容易,但我无法掌握它。我开始认为这是不可能的,因为ORDER BY是最后发生的事情,我需要SQL来对行进行ORDER,然后在runner_id上选择DISTINCT。

1 个答案:

答案 0 :(得分:0)

您的查询是使用Postgres的分析函数ROW_NUMBER()的理想选择。您希望在每个runner_id组记录中保留最新记录。下面的CTE计算每个逻辑的行号,查询仅保留最新记录。

WITH cte AS (
    SELECT runner_id, value, created_at,
           ROW_NUMBER() OVER (PARTITION BY runner_id ORDER BY created_at DESC) rn
    FROM odds
)
SELECT
    t.runner_id,
    t.value,
    t.created_at
FROM cte t
WHERE t.rn = 1

我们也可以尝试使用DISTINCT ON

SELECT DISTINCT ON (runner_id)
     runner_id, value, created_at
FROM odds
ORDER BY runner_id, created_at DESC