【问题标题】:Get the top N rows by row count in GROUP BY在 GROUP BY 中按行数获取前 N 行
【发布时间】:2021-11-27 17:32:38
【问题描述】:

我正在查询一个记录表,以查找哪些用户是我对某些记录类型的主要记录创建者。我的查询的基本起点如下所示:

SELECT recordtype, createdby, COUNT(*)
FROM recordtable
WHERE recordtype in (...)
GROUP BY recordtype, createdby
ORDER BY recordtype, createdby DESC

但是有很多用户创建了记录 - 我想进一步缩小范围。

我添加了HAVING COUNT(*) > ...,但有些记录类型只有几条记录,而另一些则有数百条记录。如果我这样做HAVING COUNT(*) > 10,我不会看到所有 9 条“XYZ”类型的记录都是由同一个人创建的,但我必须滚动浏览每个人,这些人只创建了 15、30、50 等3,500 条“ABC”类型的记录。

我只想要每种记录类型的前 5、10 名左右的创建者。

我发现了一些解决问题的“选择组中前 N 个”部分的问题,但我不知道如何将它们应用于我需要的内容。我能找到的答案是“排名依据”列是存储在表中的值,而不是聚合值。

(例如:“每个国家/地区人口最多的城市是什么?”,数据如下所示:)

Country       City     Population
United States New York 123456789
United States Chicago  123456789
France        Paris    123456789

我不知道如何应用我见过的用于回答这个问题的方法(主要是row_number())来获得COUNT(*) 的前 N ​​个。

【问题讨论】:

    标签: sql postgresql group-by


    【解决方案1】:

    这是一种方法,可以在每组中获取前 10 行:

    select * from(
        select *, row_number() over (partition by recordtype order by cnt desc) rn
        from (
           SELECT recordtype, createdby, COUNT(*) cnt
           FROM recordtable
           WHERE recordtype in (...)
           GROUP BY recordtype, createdby
        )t 
    )t where rn <= 10 
    

    【讨论】:

    • 做到了。谢谢!我确实注意到一个错字:partition recordtype by.
    【解决方案2】:

    如果我理解得很好,您想获得数量最多的前 N ​​条记录。您可以使用这样的子查询来实现这一点(我想您正在使用 MySQL 或 PostGRESQL 或 db2,在其他数据库引擎中,限制和偏移量可能会有所不同,例如在 sqlserver 中通过 select top n * from...

    SELECT A.recordtype, A.createdby, A.total FROM (
        SELECT recordtype, createdby, COUNT(*) as total
        FROM recordtable
        WHERE recordtype in (...)
        GROUP BY recordtype, createdby
    ) AS A ORDER BY recordtype, createdby, total DESC
    LIMIT 10 OFFSET 0
    

    limit 是你想要在结果页中的记录数,offset 是在进入结果页之前要跳过的记录数。

    如果你使用 sqlserver,它可能看起来像这样(还有一种方法可以应用偏移量,你可以看看这里SQL Server OFFSET and LIMIT

    SELECT TOP 10 A.recordtype, A.createdby, A.total FROM (
        SELECT recordtype, createdby, COUNT(*) as total
        FROM recordtable
        WHERE recordtype in (...)
        GROUP BY recordtype, createdby
    ) AS A ORDER BY recordtype, createdby, total DESC
    

    对于分组结果,您可以查看此帖子http://www.silota.com/docs/recipes/sql-top-n-group.html

    所以要分组获取前 10 条记录,不仅是第一个我混合了这个答案,还有下面的链接和@eshirvana 的方法

    SELECT * FROM (
        SELECT *, row_number() OVER (PARTITION recordtype BY ORDER BY total DESC) rn
        FROM (
            SELECT recordtype, createdby, COUNT(*) as total
            FROM recordtable
            WHERE recordtype in (...)
            GROUP BY recordtype, createdby
        ) t
    ) t WHERE total <= 10 
    

    【讨论】:

    • 第一个查询没有给出我正在寻找的结果。我想要 每个组中的前 N ​​条记录。所有这些查询给我的是一种记录类型的前 10 个创建者,按用户名的字母顺序排列。该链接也是我试图弄清楚的一个链接,但它没有回答“top N by count”部分。
    • 我更新了答案以适应@eshirvana 的答案以完成答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多