【问题标题】:Cumulative count of duplicates重复的累积计数
【发布时间】:2014-11-12 22:46:13
【问题描述】:

对于一个看起来像的表

ID    | Value
-------------
1     | 2
2     | 10
3     | 3
4     | 2
5     | 0
6     | 3
7     | 3

我想为表格中出现的每个Value 计算具有更高Value 的ID 数量,即

Value | Position
----------------
10    | 0
3     | 1
2     | 4
0     | 6

这相当于ValueORDER BY Value 排序中的偏移量。

我已经考虑通过计算重复的数量来做到这一点

SELECT Value, count(*) AS ct FROM table GROUP BY Value";

然后累积结果,但我想这不是最佳方法(我也没有设法相应地组合命令)

如何有效地计算这个(几十万行)?

【问题讨论】:

    标签: sql postgresql window-functions


    【解决方案1】:

    对于window function rank()(不是相关的dense_rank())来说,这似乎是一个绝佳的机会:

    SELECT DISTINCT ON (value)
           value, rank() OVER (ORDER BY value DESC) - 1 AS position
    FROM   tbl
    ORDER  BY value DESC;
    

    rank() 从 1 开始,而你的计数从 0 开始,所以要减去 1。

    添加一个DISTINCT 步骤(DISTINCT ON 在这里稍微便宜一些)来删除重复的行(在计算计数等级之后)。 DISTINCT 在窗口函数之后应用。此相关答案中的详细信息:

    结果完全符合要求。
    value 上的索引将有助于提高性能。

    SQL Fiddle.

    【讨论】:

    • 难以置信。我不会想到命令/功能存在!非常感谢你。 rank() 对于我尝试的结果来说甚至更好,所以一切都很棒!
    【解决方案2】:

    如果您对窗口功能不满意,您也可以试试这个:

    SELECT t1.value, COUNT(DISTINCT t2.id) AS position
      FROM tbl t1 LEFT OUTER JOIN tbl t2
        ON t1.value < t2.value
     GROUP BY t1.value
    

    注意自加入。

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 2017-03-23
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 1970-01-01
      相关资源
      最近更新 更多