使用最新时间为每个键选择两行

时间:2014-11-17 21:18:32

标签: mysql sql select group-by greatest-n-per-group

我在MySQL表tbl_test中有数据:

create table `tbl_test` (
  `id` INT(10) NOT NULL UNIQUE,
  `value` char(30),
  `time` timestamp,
  `id1` int(10)
  );

INSERT INTO
`tbl_test` (`id`,`value`,`time`,`id1`)
VALUES
  ('3638','value1','2014-11-16 02:01:48','1'),
  ('3639','value2','2014-11-14 13:00:45','1'),
  ('3642','value3','2014-11-14 13:00:40','1'),
  ('3769','value4','2014-11-15 22:21:50','2'),
  ('3770','value5','2014-11-15 22:21:55','2'),
  ('3789','value6','2014-11-14 16:08:20','2'),
  ('3870','value7','2014-11-16 02:01:49','1');

所需结果(每id1行2行,如order by time desc limit 2每行{/ p>}:

+------+--------+---------------------+----+
| id   | value  | time                |id1 |
+------+--------+---------------------+----+
| 3769 | value4 | 2014-11-15 22:21:50 | 2  |
| 3770 | value5 | 2014-11-15 22:21:55 | 2  |
| 3638 | value1 | 2014-11-16 02:01:48 | 1  |
| 3870 | value7 | 2014-11-16 02:01:49 | 1  |
+------+--------+---------------------+----+

我的查询最接近:

select * from (
   select max(id) as id from tbl_test group by id1
   union all
   select max(id) from tbl_test tmp1
   where id not in (SELECT max(id) from tbl_test tmp2 where tmp1.id1 = tmp2.id1)
   group by id1
   ) as tmp
left join tbl_test USING(id);

+------+--------+---------------------+----+
| id   | value  | time                |id1 |
+------+--------+---------------------+----+
| 3770 | value5 | 2014-11-15 22:21:55 | 2  |
| 3789 | value6 | 2014-11-14 16:08:20 | 2  |
| 3642 | value3 | 2014-11-14 13:00:40 | 1  |
| 3870 | value7 | 2014-11-16 02:01:49 | 1  |
+------+--------+---------------------+----+

但我对max(id)有疑问。表是网格化的,我需要时间desc限制2。

http://sqlfiddle.com/#!2/f6f53/3

2 个答案:

答案 0 :(得分:1)

认为这就是你要找的东西:

&#34;对于每个id1,返回最新time(最大id为决胜局)的两行&#34; :< / p>

使用标准SQL 窗口函数,这很简单:

SELECT id, value, time, id1
FROM  (
   SELECT t.*
        , row_number() OVER (PARTITION BY id1 ORDER BY time DESC, id DESC) AS rn
   FROM   tbl_test t   
   ) sub
WHERE  rn < 3
ORDER  BY id1 DESC, time DESC, id DESC;

MySQL 不提供窗口功能。您可以使用用户定义的变量替换:

SELECT id, value, time, id1
FROM  (
   SELECT t.*
        , @rn := CASE WHEN @prev = id1 THEN @rn + 1 ELSE 1 END rn
        , @prev := id1
   FROM   tbl_test t
       , (SELECT @rn := 0) r
   ORDER BY id1 DESC, time DESC, id DESC
   ) sub
WHERE  rn < 3
ORDER  BY id1 DESC, time DESC, id DESC;

SQL Fiddle.

相关问题:

答案 1 :(得分:0)

似乎您希望每个id1的行具有最近的时间。

select t.*
from tbl_test t  join
     (select id1, max(time) as maxtime
      from tbl_test
      group by id1
     ) tt
     on t.id1 = tt.id1 and t.time = tt.maxtime
order by time;

http://sqlfiddle.com/#!2/4e010/1/0