SQL - 选择按多个字段分组的前 n 个,按计数排序
Posted
技术标签:
【中文标题】SQL - 选择按多个字段分组的前 n 个,按计数排序【英文标题】:SQL - Select top n grouped by multiple fields, ordered by count 【发布时间】: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 解释都将不胜感激。
【问题讨论】:
【参考方案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
【讨论】:
以上是关于SQL - 选择按多个字段分组的前 n 个,按计数排序的主要内容,如果未能解决你的问题,请参考以下文章