3

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

(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 Query 从上表中检索所有第二高的日期?

预期结果:

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
4

6 回答 6

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 类别分组。然后我编写了实际的查询来获得结果,并连接到派生表,所以我确保我得到那个特定MUSICAND的正确行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

于 2013-10-22T12:45:18.757 回答
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。

于 2013-10-22T11:19:54.283 回答
0

您可以尝试以下查询 -

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

我认为这就像找到员工的第二高薪水 -示例

于 2013-10-22T12:14:06.007 回答
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;
于 2013-10-22T12:40:51.280 回答
-1

select id,music,[uid] from (select row_number() over (PARTITION BY id order by [date] desc) as rn,id,music,[uid] from table_name) a where rn = 2 -- insted of 2 u可以更改为您想要的任何数字

于 2013-10-22T12:21:34.737 回答
-2

尝试这个

这是 SQL 查询

SELECT * FROM 
(SELECT 
ROW_NUMBER() OVER (PARTITION BY Music ORDER BY Date DESC) NO,
*
FROM UrTable) AS T1 WHERE no = 2
于 2013-10-22T12:42:09.820 回答