简体   繁体   English

如何选择列中前5个最频繁的值

[英]How to select top 5 most frequent value in a column

I want to select the top 5 most frequent albums from a database, using this database: http://www.sqlitetutorial.net/tryit/query/sqlite-inner-join/#3 我想使用以下数据库从数据库中选择最频繁的5张专辑: http : //www.sqlitetutorial.net/tryit/query/sqlite-inner-join/#3

with this query: 与此查询:

SELECT
  albums.title AS Album,
  artists.name AS Artist,
  COUNT(albums.title ) as TitleCount
FROM tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
INNER JOIN artists ON artists.artistid = albums.artistid
GROUP BY 
  albums.albumid 
ORDER BY 
  TitleCount DESC

Limit 5 is not a good solution, as in my case, there are 2 albums with 25 titles, what I want is the top 5 by titleCount value. 限制5不是一个好的解决方案,因为在我的情况下,有2张专辑有25个标题,我想要的是titleCount值排在前5位的专辑。 It seems like limit doesn't take COUNT, but integers 似乎limit不需要COUNT,但整数

expected result: 预期结果:

|Album               |Artist       |TitleCount|
|Greatest Hits       |Lenny Kravitz|57        |  
|Minha Historia      |Chico Buarque|34        |
|Unplugged           |Eric Clapton |30        |
|Lost, Season 3      |Lost         |26        |
|Lost, Season 1      |Lost         |25        |
|The Office, Season 3|The Office   |25        |

ps: this might be a duplicate of SQL - Most frequent value in column of joined tables , but I can't apply it to mine ps:这可能是SQL的重复-联接表的列中最常用的值 ,但是我无法将其应用于我的值

MySQL's and SQLite's LIMIT clauses both lack a WITH TIES option, which is what you'd need here. MySQL和SQLite的LIMIT子句都缺少WITH TIES选项,这是您在这里需要的。 So use a subquery instead: Select the five greatest numbers of tracks (which is a rare case where you actually combine GROUP BY with DISTINCT - GROUP BY to get counts per album, DISTINCT to get the five highes different counts), then select the albums having as many tracks. 因此,请改用子查询:选择曲目数量最多的五个(在极少数情况下,您实际上将GROUP BYDISTINCT结合使用DISTINCT GROUP BY获取每个专辑的计数, DISTINCT获取五个最高的不同计数),然后选择专辑有尽可能多的曲目。 As this is about an aggregation result, this belongs in the HAVING clause: 因为这是关于聚合结果的,所以它属于HAVING子句:

SELECT
  albums.title AS Album,
  artists.name AS Artist,
  COUNT(*) as TitleCount
FROM tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
INNER JOIN artists ON artists.artistid = albums.artistid
GROUP BY albums.albumid 
HAVING COUNT(*) IN
(
  SELECT DISTINCT COUNT(*)
  FROM tracks
  GROUP BY albumid
  ORDER BY count(*) DESC
  LIMIT 5
)
ORDER BY TitleCount DESC;

Use below code 使用以下代码

    SELECT
  albums.title AS Album,
  artists.name AS Artist,
  COUNT(*) as TitleCount
FROM tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
INNER JOIN artists ON artists.artistid = albums.artistid
GROUP BY albums.albumid 
HAVING COUNT(*) IN
(
  SELECT DISTINCT COUNT(*)
  FROM tracks
  GROUP BY albumid
  ORDER BY count(*) DESC

)
ORDER BY TitleCount DESC LIMIT 5;

While the other answer works fine, if you're using sqlite 3.25 or newer (Or I think MySQL 8), this can be done in a simpler fashion using the dense_rank() window function : 虽然其他答案很好用,但是如果您使用的是sqlite 3.25或更高版本(或者我认为是MySQL 8),则可以使用dense_rank() 窗口函数以更简单的方式完成此操作:

WITH rankings(Album, Artist, TitleCount, ranking) AS (
  SELECT al.title, ar.name, count(al.title)
       , dense_rank() OVER (ORDER BY count(al.title) DESC)
  FROM tracks AS t
  INNER JOIN albums AS al ON al.albumid = t.albumid
  INNER JOIN artists AS ar ON ar.artistid = al.artistid
  GROUP BY al.albumid)
SELECT Album, Artist, TitleCount
FROM rankings
WHERE ranking <= 5
ORDER BY ranking;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM