我已经看到了几篇关于SO的文章,它们涉及在另一个属性分组的一个属性中选择最大值,但是我一直无法复制结果,而且我不确定自己在做什么错。

我收到一个SQL异常,该异常使我需要检查手册以了解我的SQL版本(使用MySQL)。

关系


用户(UID,UName,状态)
歌曲(SID,AID,SName,ReleaseDate)
艺术家(AID,AName,说明)
记录(SID,UID,日期)


我正在尝试SELECT 2018年的用户ID和最多播放的歌曲(按名称)。我的尝试如下。

我的基本原理是获得按用户ID(UID)和每首歌曲按歌曲ID(SID)分组的关系以及每首歌曲的计数,然后加入歌曲名称并过滤MAX值,但是我在这里遗漏了一些重要的东西,并且将我的答案与其他类似帖子的关系进行了比较并没有太大帮助

SELECT UID, SName
FROM
(SELECT UID, SName, COUNT(listenDate) AS listen_date_count
    FROM record
    LEFT JOIN song ON song.SID = record.SID
    WHERE YEAR(Date) = 2018
    GROUP BY UID, SName) AS records_2018
GROUP BY UID, SName
HAVING MAX(listen_date_count);

最佳答案

这是在子查询中按用户/歌曲元组进行聚合的良好起点。我只需添加一个NOT EXISTS条件,以确保没有其他具有最高视图计数的元组。

以下查询应为您提供2018年每个用户观看次数最多的歌曲:

SELECT *
FROM (
    SELECT r.UID, r.SID, s.SName, COUNT(*) AS listen_date_count
    FROM record r
    INNER JOIN song s ON s.SID = r.SID
    WHERE YEAR(r.Date) = 2018
    GROUP BY r.UID, r.SID, s.SName
) x WHERE NOT EXISTS (
    SELECT 1
    FROM record r1
    WHERE YEAR(r1.Date) = 2018 AND r1.UID = x.UID AND r1.SID != x.SID
    GROUP BY r1.UID, r1.SID
    HAVING COUNT(*) > x.listen_date_count
)


PS:


您需要在group by子句中使用SID;相反,通过SName分组是不安全的,因为两个具有相同名称的不同歌曲最终会错误地分组在一起
使用联接或相关子查询时,您想在列名前加上相关的表前缀。这样可以避免冲突,并且通常使事情更易于理解和维护。

关于mysql - 每个属性值的SQL最大值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54847265/

10-11 18:07