【问题标题】:Select two rows per key with the latest time每个键选择两行最新时间
【发布时间】:2015-01-14 22:10:14
【问题描述】:

我在 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):

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

【问题讨论】:

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


    【解决方案1】:

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

    “对于每个id1,返回最新的time 的两行(最大的id 作为决胜局)”

    使用标准 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.

    相关问题:

    【讨论】:

      【解决方案2】:

      您似乎想要每个 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

      【讨论】:

      • @ВячеславВе 。 . .那我不明白你在做什么。
      • 我已经编辑了“目标”,现在它有 2 行 id1=id1 和最新的时间戳,但它们不相等。
      猜你喜欢
      • 2013-06-24
      • 2014-08-27
      • 1970-01-01
      • 2021-12-30
      • 2016-12-23
      • 1970-01-01
      • 2017-03-17
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多