【问题标题】:SELECT DISTINCT ON in Postgresql returns multiple rowsPostgresql 中的 SELECT DISTINCT ON 返回多行
【发布时间】:2018-07-24 15:38:16
【问题描述】:

当我跑步时

SELECT DISTINCT ON (ts) * 
FROM tbl 
WHERE clause=100 
AND ts <= '2018-04-02 15:11:18.819000' 
AND ts > '2018-04-02 15:06:18.819000' 
ORDER BY ts, version ASC;

我希望单行对应于满足条件的最大 ts,并通过取最低 version 来打破平局。

查询返回

         ts                     version
'2018-04-02 15:07:04.828'   ...   1
'2018-04-02 15:07:05.706'   ...   1

我不明白为什么要返回两个不明显的ts。是否有类似的查询会返回所需的结果?

【问题讨论】:

  • 两行不同。

标签: sql postgresql distinct-on


【解决方案1】:

Distinct on 为子句后面的每个键组合返回一行。在这种情况下,每个ts 将出现一次。哪一个?这是由order by 决定的。 distinct on 键后面的键确定第一个,因此这将是最低版本号。

您的查询似乎产生了合理的结果。

如果您希望结果集中的一行具有最大的ts,则使用order bylimit/fetch first 1 row only

SELECT * 
FROM tbl 
WHERE clause = 100 AND
      ts <= '2018-04-02 15:11:18.819000' AND
      ts > '2018-04-02 15:06:18.819000' 
ORDER BY ts DESC, version ASC
FETCH FIRST 1 ROW ONLY;

注意ORDER BY 中的ts DESC,以获取ts 的最新值。

【讨论】:

  • 谢谢,不知怎的,我知道 distinct on 应该只返回一行。
【解决方案2】:

据我了解,你想得到version 和最后一个ts

在您的情况下,最好不要使用DISTINCT,而是使用GROUP BY

例如这段代码可以解决你的问题:

SELECT max(ts), version 
FROM tbl 
WHERE clause=100 
  AND ts <= '2018-04-02 15:11:18.819000' 
  AND ts > '2018-04-02 15:06:18.819000' 
GROUP BY version;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 2012-10-07
    • 2014-03-13
    • 1970-01-01
    相关资源
    最近更新 更多