【问题标题】:Finding Top Values using SQL Query使用 SQL 查询查找最高值
【发布时间】:2021-09-08 11:05:08
【问题描述】:

对 SQL 相当陌生,我正在为一个音乐数据库编写一个练习查询,我需要在 2009 年 1 月按播放时间拉取前 10 首歌曲。这是架构:

到目前为止,这是我的声明。我只是想知道我是否朝着正确的方向前进,因为我知道为了创建查询,我需要对每首歌曲的播放时间求和,并将其包含在 ORDER BY 子句中:

SELECT song_name
FROM music LEFT JOIN client
ON music.id = client.music_id
WHERE client.date BETWEEN '2009-01-01' AND '2009-01-31'
ORDER BY SUM(client.playing_hrs) DESC; 

【问题讨论】:

    标签: sql database join select data-analysis


    【解决方案1】:

    在 SQL Server 中,您可以使用此查询完成您的任务。请参阅我的答案底部,了解我在哪里解释了我在查询中做某些事情的更多原因,以便您可以将其应用于其他 RDBMS

    select top(10) m.song_name,
           total_song_hrs
           from (
    select m.song_name, 
           sum(c.playing_hrs) as total_song_hrs
         from music m 
         
         join clients c 
         on m.id = c.music_id 
         
         where c.date >= '2009-01-01' and c.date <= '2009-01-31'
         group by m.song_name
    ) s
    order by total_song_hrs desc
    

    首先,您需要将您的音乐表加入您的客户表,以便访问一首歌曲的播放小时数。然后,您将过滤掉所有在 2009 年 1 月之外播放时间的歌曲。然后您将按歌曲名称分组,以便汇总歌曲的播放时间。最后,您将上述内容包装在子查询中,在父查询中您需要使用排序依据,以便您可以选择前 10 首歌曲。

    【讨论】:

      【解决方案2】:

      根据您的 SQL 方言,您将需要某种 LIMIT 或 TOP 子句。 Microsoft SQL Server 使用 TOP。使用 GROUP BY 选择您的总金额也可能是有益的。

      SELECT TOP 10 song_name, 
             SUM(client.playing_hrs) as hours_played
      FROM music LEFT JOIN client
      ON music.id = client.music_id
      WHERE client.date BETWEEN '2009-01-01' AND '2009-01-31'
      GROUP BY song_name
      ORDER BY SUM(client.playing_hrs) DESC;
      

      这将检索前十首歌曲及其播放时间。

      【讨论】:

        【解决方案3】:

        这是最好的窗口函数。

        使用 OVER() 和 ROW_NUMBER() (ROW_NUMBER 函数的名称因 DBMS 而异,它适用于 sqlite 和 postgresql)

        假设你有一个关系 R(a,b)

        您可以通过升序使用 a 的值来获得前 10 个元组:

        WITH T as (
          SELECT a, b, row_number() over (order by a) as n FROM R)
        select * from T where n <= 10;
        

        在你的情况下,你可以这样做:

        WITH R as (
           SELECT song_name, sum(client.playing_hrs) as sum
           FROM music LEFT JOIN client
           ON music.id = client.music_id
           WHERE client.date BETWEEN '2009-01-01' AND '2009-01-31'
        ),
         T as (
              SELECT song_name, row_number() over (order by sum desc) as n FROM R)
            select * from T where n <= 10;
        

        此外,您还可以获得每个元组的确切位置(1、2、3、...等)。

        当然,您可以简化此查询。但是这个多步骤的子查询更清楚地显示了解决方案。

        【讨论】:

          【解决方案4】:

          您应该有一个带有聚合 SUM() 的 GROUP BY。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-11-03
            • 2018-04-12
            • 2013-05-14
            • 1970-01-01
            • 2016-04-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多