简体   繁体   中英

Finding each record having second largest date for each `key' column in mysql?

With below code I'm able to get every key with max key_date value.

SELECT *
FROM `log`
GROUP BY `key`
ORDER BY `key_date` DESC

But how can i get every records matching second largest date?

id  Key   key_date
--------------------
1   Key1  10/10/2010
2   Key1  10/10/2009
3   Key2  10/10/2011
4   Key2  10/10/2012
5   Key1  10/10/2008

I need to match record 2 (second largest among key1) and 3 (second largest among key2)

2   Key1  10/10/2009
3   Key2  10/10/2011

This should work if you're using MySQL 8.0 or higher - I think a windowing function would be a good way to do this.

SELECT id, Key, Key_date
    FROM
    (
    SELECT id, KEY, key_date, 
     ROW_NUMBER() OVER(PARTITION BY Key ORDER BY key_date DESC) AS row_n
    FROM log
    ) a1
    WHERE row_n = 2

You can use correlated subquery :

SELECT l.* 
FROM `log` l 
WHERE key_date = (SELECT l1.`key_date`
                  FROM  `log` l1
                  WHERE l1.`key` = l.`key`
                  ORDER BY l1.`key_date` DESC
                  LIMIT 1 OFFSET 1
                 );

This will work for any MySQL Version. Later versions will support windowed functions.

Edited for Raymond's input, but for versions >=8 ... probably just use windowed functions anyway.

http://sqlfiddle.com/#!9/fe157c/9

CREATE TABLE TEST_DATA (
    ID_Field VARCHAR(100),
    Test_Integer INTEGER
  );

INSERT INTO TEST_DATA VALUES ('1',1);
INSERT INTO TEST_DATA VALUES ('1',2);
INSERT INTO TEST_DATA VALUES ('1',3);
INSERT INTO TEST_DATA VALUES ('2',5);
INSERT INTO TEST_DATA VALUES ('2',6);
INSERT INTO TEST_DATA VALUES ('2',-1);
INSERT INTO TEST_DATA VALUES ('2',4);
INSERT INTO TEST_DATA VALUES ('3',1);
INSERT INTO TEST_DATA VALUES ('3',2);

SELECT ID_Field,
       Test_Integer
  FROM (SELECT TD1.ID_field,
               TD1.Test_Integer,
               COUNT(TD2.ID_Field) + 1 rn
          FROM TEST_DATA TD1
          LEFT
          JOIN TEST_DATA TD2
            ON TD1.ID_Field = TD2.ID_Field
           AND TD1.Test_Integer < TD2.Test_Integer
         GROUP
            BY TD1.ID_Field,
               TD1.Test_Integer
         ORDER
            BY TD1.ID_Field,
               TD1.Test_Integer
       ) TMP
 WHERE TMP.rn = 2;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM