每个属性值的SQL最大值

时间:2019-02-23 23:25:06

标签: mysql sql

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

我收到一条SQL异常,提示我检查我的SQL版本手册(使用MySQL)。

关系

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

我正在尝试SELECT的用户ID和2018年最受欢迎的歌曲(按名称)。我的尝试在下面。

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

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);

2 个答案:

答案 0 :(得分:0)

这是在子查询中按用户/歌曲元组进行聚合的良好起点。我只需添加一个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进行分组是不安全的,因为两个具有相同名称的不同歌曲最终会错误地分组在一起

  • 在使用联接或相关子查询时,您想在列名前加上相关的表前缀。这样可以避免冲突,并通常使事情更易于理解和维护。

答案 1 :(得分:0)

您只能首先LIMIT观看歌曲。

然后选择前1首歌曲,再选择LIMIT(上限)用户。

SELECT usermost.UID, song.SName
FROM
(
   SELECT songmost.SID, rec.UID
   FROM
   (
      SELECT SID
      FROM record 
      WHERE YEAR(`Date`) = 2018
      GROUP BY SID
      ORDER BY COUNT(*) DESC, COUNT(DISTINCT UID) DESC
      LIMIT 1
  ) songmost
  JOIN record rec 
    ON rec.SID = songmost.SID AND YEAR(rec.`Date`) = 2018
  GROUP BY rec.SID, rec.UID
  ORDER BY COUNT(*) DESC
  LIMIT 1
) usermost
LEFT JOIN song ON song.SID = usermost.SID

示例:

CREATE TABLE user (
  UID int primary key not null auto_increment, 
  UName varchar(30) not null, 
  State int not null default 0
);
CREATE TABLE artist (
  AID int primary key not null auto_increment, 
  AName varchar(30) not null, 
  Description  varchar(300)
);
create table song (
  SID int primary key not null auto_increment, 
  AID int not null,
  SName varchar(30) not null, 
  ReleaseDate date not null,
  constraint fk_song_aid foreign key (AID) references artist(AID)
);
create table record (
  SID int not null, 
  UID int not null, 
  `Date` date not null,
  constraint fk_record_sid foreign key (SID) references song(SID)
);
insert into user (UName, State) values 
('John Doe', 0), 
('Jane Sheppard', 1);
insert into artist (AName, Description) values 
('Imagine Dragons', 'American pop rock band'),
('Yuki Kajiura', 'Japanese musician, composer and record producer');
insert into song (AID, SName, ReleaseDate) values
(1, 'Whatever it takes', '2017-10-06'),
(2, 'I talk to the rain', '2005-07-05');
insert into  record (SID, UID, `Date`) values 
(1,1,'2018-01-01'),(1,1,'2018-02-01'),(1,2,'2018-03-01'),
(2,1,'2018-04-01'),(2,2,'2018-01-01');
select rec.SID, song.SName, user.UName, artist.AName, COUNT(*) As Total
from record rec
left join song on song.SID = rec.SID
left join user on user.UID = rec.UID
left join artist on artist.AID = song.AID
group by rec.SID, rec.UID
SID | SName              | UName         | AName           | Total
--: | :----------------- | :------------ | :-------------- | ----:
  1 | Whatever it takes  | John Doe      | Imagine Dragons |     2
  1 | Whatever it takes  | Jane Sheppard | Imagine Dragons |     1
  2 | I talk to the rain | John Doe      | Yuki Kajiura    |     1
  2 | I talk to the rain | Jane Sheppard | Yuki Kajiura    |     1
SELECT usermost.UID, song.SName
FROM
(
   SELECT songmost.SID, rec.UID
   FROM
   (
      SELECT SID
      FROM record 
      WHERE YEAR(`Date`) = 2018
      GROUP BY SID
      ORDER BY COUNT(*) DESC, COUNT(DISTINCT UID) DESC
      LIMIT 1
  ) songmost
  JOIN record rec 
    ON rec.SID = songmost.SID AND YEAR(rec.`Date`) = 2018
  GROUP BY rec.SID, rec.UID
  ORDER BY COUNT(*) DESC
  LIMIT 1
) usermost
LEFT JOIN song ON song.SID = usermost.SID
UID | SName            
--: | :----------------
  1 | Whatever it takes

db <>提琴here