从mysql表中获得第二高的值

时间:2013-10-22 11:12:47

标签: 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-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 UID MUSIC DATE 
3   0   a   2013-10-22
5   0   b   2013-10-11
9   0   c   2013-10-25
11  0   d   2013-10-10

6 个答案:

答案 0 :(得分:5)

好的,我想我有答案。 请检查一下:

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

首先,我在DATE创建了GROUP_CONCAT,按desc排序,因此我可以使用Substring_index获取第二个DATE,当然,按MUSIC对所有内容进行分组, 所以日期按照各自的MUSIC类别进行分组。 然后我编写了实际的查询以获取结果,并加入到派生表中,因此我确保为特定的MUSIC AND DATE获取正确的行。

这是SQLFiddle

<强>更新

如果您想通过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

并更新了SQLFiddle

答案 1 :(得分:1)

从这个SQLFiddle:http://sqlfiddle.com/#!2/fd47a2/7

SELECT tbl.UID, tbl.MUSIC, MAX(tbl.DATE)
FROM tbl
LEFT JOIN (
    SELECT UID, MUSIC, MAX(DATE) as DATE
    FROM tbl
    GROUP BY UID, MUSIC) AS tbl2
  ON tbl.UID = tbl2.UID
    AND tbl.MUSIC = tbl2.MUSIC
    AND tbl.DATE = tbl2.DATE
WHERE tbl2.UID IS NULL
GROUP BY tbl.UID, tbl.MUSIC

但它没有ID,如果你需要,那么IMO,你需要使用上面的查询作为另一个连接到原始表来获取ID。

答案 2 :(得分:0)

您可以尝试以下查询 -

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

我认为这可以找到员工的第二高薪 - Example

答案 3 :(得分:0)

可能有一个更优雅的解决方案,但这是一种方式......

 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;

答案 4 :(得分:-1)

选择id,music,[uid] from(select row_number()over(PARTITION BY id order by [date] desc)as rn  ,id,音乐,来自table_name的[uid])a其中rn = 2 - 2的内容可以更改为任何你想要的数字

答案 5 :(得分:-2)

试试这个

这是SQL查询

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