【问题标题】:get all second highest from a mysql table从 mysql 表中获得所有第二高的
【发布时间】:2013-10-31 05:30:46
【问题描述】:

我有一个表,有如下四个字段,

(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

【问题讨论】:

  • “所有第二高的日期”是什么意思?
  • 您想获取每首音乐的第二高日期吗?

标签: mysql group-by groupwise-maximum


【解决方案1】:

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

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

【讨论】:

  • 谢谢!解决了这个问题:)
  • 没问题,很有趣;)
【解决方案2】:

来自这个 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。

【讨论】:

  • 抱歉 - 应该是 LEFT JOIN
  • 同样的问题。(查询结果为空)
  • @user2055052 - 错误比它更核心,请参阅解决方案中的 sqlfiddle 链接。
【解决方案3】:

你可以试试下面的查询——

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

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

【讨论】:

    【解决方案4】:

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

     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;
    

    【讨论】:

      【解决方案5】:

      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 你可以更改为你想要的任何数字

      【讨论】:

      • mysql中没有row_number()
      • 对不起,是sql server
      【解决方案6】:

      试试这个

      这是 SQL 查询

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

      【讨论】:

      • MySQL 中没有 row_number()。
      • 那你为什么要标记 SQL。
      • 这里标记为 MySQL
      • 你最近成功了
      • ROW_NUMBER 不是(据我所知)SQL 标准的一部分——尽管我同意,出于不同的原因,不应使用 SQL 标记。我现在已经删除了。
      猜你喜欢
      • 2013-09-15
      • 1970-01-01
      • 2011-07-18
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多