【问题标题】:SQL - Select top n grouped by multiple fields, ordered by countSQL - 选择按多个字段分组的前 n 个,按计数排序
【发布时间】:2018-05-17 19:39:31
【问题描述】:

我试图在按多个属性分组时查找前 n 条记录。我相信它与this problem 有关,但我很难根据我的情况调整所描述的解决方案。

为简化起见,我有一个包含列的表(did 是 device_id 的缩写):

id int
did int
dateVal dateTime

我正在尝试查找每一天的前 n 个设备 ID,其中行数最多。

例如(忽略id和dateTime的时间部分),

did dateVal
1   2017-01-01
1   2017-01-01
1   2017-01-01
2   2017-01-01
3   2017-01-01
3   2017-01-01

1   2017-01-02
1   2017-01-02
2   2017-01-02
2   2017-01-02
2   2017-01-02
3   2017-01-02

找到前 2 个将产生...

1, 2017-01-01
3, 2017-01-01
2, 2017-01-02
1, 2017-01-02

我目前的幼稚方法只给我所有日期的前 2 名。

--Using SQLite
select date(dateVal) || did 
from data 
group by date(dateVal), did
order by count(*) desc 
limit 2

我正在使用连接运算符,以便以后可以提取行。

我正在使用 SQLite,但任何一般的 SQL 解释都将不胜感激。

【问题讨论】:

    标签: sqlite greatest-n-per-group limit-per-group


    【解决方案1】:

    类似于this question,定义一个计算所需组的所有设备计数的 CTE,然后在WHERE ... IN 子查询中使用它,仅限于该日期的前 2 个设备:

    WITH device_counts AS (
      SELECT did, date(dateval) AS dateval, COUNT(*) AS device_count
      FROM data
      GROUP BY did, date(dateval)
    )
    SELECT did, date(dateval) FROM device_counts DC_outer
    WHERE did IN (
      SELECT did
      FROM device_counts DC_inner
      WHERE DC_inner.dateval = DC_outer.dateval
      GROUP BY did, date(dateval)
      ORDER BY DC_inner.device_count DESC LIMIT 2
    )
    ORDER BY date(dateval), did
    

    【讨论】:

    • 终于有时间试试这个方法了。相当肯定我正在处理的数据量导致查询挂起。我会让它通宵运行。同时,是否有可能以某种方式优化查询?比如可能不使用 date() 转换函数?
    • 可能。 (did, date) 上的索引可能也会有所帮助。如果不知道每个表的 # 行以及您已经拥有的索引,很难说。
    【解决方案2】:

    我使用 sql server 测试了查询

    select top 2 did, dateVal
    from (select *, count(*) as c
          from test
          group by did,dateVal) as t
    order by t.c desc 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2013-01-12
      • 2018-07-04
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      相关资源
      最近更新 更多