从mysql表中获取所有次高值

从mysql表中获取所有次高值,mysql,group-by,groupwise-maximum,Mysql,Group By,Groupwise Maximum,我有一个包含四个字段的表,如下所示 UID是用户ID ID UID MUSIC DATE 1 0 a 2013-10-20 2 0 a 2013-10-21 3 0 a 2013-10-22 4 0 a 2013-10-24 5 0 b 2013-10-11 8 0 b 2013-10-15 10 0 c 2013-10-26 9 0 c 2013-10-25 7 0 c 2013-10-

我有一个包含四个字段的表,如下所示

UID是用户ID

ID UID MUSIC DATE 
1   0   a   2013-10-20
2   0   a   2013-10-21
3   0   a   2013-10-22
4   0   a   2013-10-24
5   0   b   2013-10-11
8   0   b   2013-10-15
10  0   c   2013-10-26
9   0   c   2013-10-25
7   0   c   2013-10-20
6   0   c   2013-10-18
11  0   d   2013-10-10
如何使用MySQL查询从上表中检索所有第二高的日期

预期结果:

ID UID MUSIC DATE 
3   0   a   2013-10-22
5   0   b   2013-10-11
9   0   c   2013-10-25

从这把小提琴:


但是,它没有ID,如果需要,您需要使用上述查询作为原始表的另一个联接来获取ID。

您可以尝试以下查询-

SELECT ID, UID, MUSIC, MAX(DATE) FROM TableName
WHERE DATE NOT IN (SELECT MAX(DATE) FROM TableName )

我认为这有点像找到员工的第二高工资-

选择id,音乐,[uid]从按id划分的行编号中选择,按[date]描述为rn
,id,music,[uid]来自表a,其中rn=2,而不是2u可以更改为您想要的任何数字

可能有一个更优雅的解决方案,但这里有一种方法

 SELECT a.* 
   FROM
      ( SELECT x.*
          FROM my_music x 
          JOIN my_music y 
            ON y.uid = x.uid 
           AND y.music = x.music 
           AND y.date >= x.date 
         GROUP 
            BY id
        HAVING COUNT(*) <= 2
      ) a
   JOIN
      ( SELECT x.*
          FROM my_music x 
          JOIN my_music y 
            ON y.uid = x.uid 
           AND y.music = x.music 
           AND y.date >= x.date 
         GROUP 
            BY id
        HAVING COUNT(*) <= 2
      ) b
     ON b.uid = a.uid
    AND b.music = a.music
    AND b.date <= a.date
  GROUP 
     BY id
 HAVING COUNT(*) = 1;
试试这个

这是SQL查询

SELECT * FROM 
(SELECT 
ROW_NUMBER() OVER (PARTITION BY Music ORDER BY Date DESC) NO,
*
FROM UrTable) AS T1 WHERE no = 2

好的,我想我知道答案了。 请检查以下内容:

SELECT tbl.ID, tbl.UID, tbl.MUSIC, tbl.DATE
FROM tbl
INNER JOIN
(
SELECT MUSIC,
       Substring_index(Substring_index(gdate, ',', 2), ',', -1) AS sec_date
FROM   (SELECT MUSIC               ,
               GROUP_CONCAT(DATE order by DATE desc separator ",") AS gdate
        FROM   tbl
        GROUP  BY MUSIC) t1
) AS tbl2
  ON tbl.MUSIC=tbl2.MUSIC
    AND tbl.DATE=tbl2.sec_date
首先,我创建了GROUP_CONCAT on DATE,按desc排序,因此我可以使用Substring_index获得第二个日期,当然,还可以按音乐对所有内容进行分组, 因此,日期会根据各自的音乐类别进行分组。 然后,我编写了实际的查询以获得结果,并将其与派生表连接,这样我就可以确保获得特定音乐和日期的正确行

这是我的答案

更新

如果要按UID进行进一步筛选,只需将WHERE添加到内部查询,如下所示:

SELECT tbl.ID, tbl.UID, tbl.MUSIC, tbl.DATE
FROM tbl
INNER JOIN
(
SELECT MUSIC,
       Substring_index(Substring_index(gdate, ',', 2), ',', -1) AS sec_date
FROM   (SELECT MUSIC               ,
               GROUP_CONCAT(DATE order by DATE desc separator ",") AS gdate
        FROM   tbl
        WHERE UID=1 -- add filter here
        GROUP  BY MUSIC) t1
) AS tbl2
  ON tbl.MUSIC=tbl2.MUSIC
    AND tbl.DATE=tbl2.sec_date

和更新的

您所说的所有第二高日期是什么意思?您想为每首音乐获取第二高的日期吗?很抱歉-应该是同一个问题。查询结果是null@user2055052-错误比,请参阅解决方案中的sqlfiddle链接。MySQL中没有行号。那么您为什么要标记SQL。最近您在此处标记了MySQL。据我所知,您的chenggedROW\u号不是SQL标准的一部分-尽管我同意,出于其他原因,不应该使用SQL标记。我现在已经删除了它。MySQL中没有行号。对不起,这是sql Server的行号。谢谢!解决了这个问题:没问题,很有趣;
SELECT tbl.ID, tbl.UID, tbl.MUSIC, tbl.DATE
FROM tbl
INNER JOIN
(
SELECT MUSIC,
       Substring_index(Substring_index(gdate, ',', 2), ',', -1) AS sec_date
FROM   (SELECT MUSIC               ,
               GROUP_CONCAT(DATE order by DATE desc separator ",") AS gdate
        FROM   tbl
        GROUP  BY MUSIC) t1
) AS tbl2
  ON tbl.MUSIC=tbl2.MUSIC
    AND tbl.DATE=tbl2.sec_date
SELECT tbl.ID, tbl.UID, tbl.MUSIC, tbl.DATE
FROM tbl
INNER JOIN
(
SELECT MUSIC,
       Substring_index(Substring_index(gdate, ',', 2), ',', -1) AS sec_date
FROM   (SELECT MUSIC               ,
               GROUP_CONCAT(DATE order by DATE desc separator ",") AS gdate
        FROM   tbl
        WHERE UID=1 -- add filter here
        GROUP  BY MUSIC) t1
) AS tbl2
  ON tbl.MUSIC=tbl2.MUSIC
    AND tbl.DATE=tbl2.sec_date