MYSQL根据输入天数选择最后两个条目块

时间:2014-05-01 16:11:33

标签: mysql

我有一张桌子,一天有多个条目。我想要最后两组参赛作品。

值| timeIn | ID

enter image description here

select * from db.table t
where t.r_id = 76703
order by timeIn DESC
LIMIT 2

我想通过timeIn(时间列)添加一个组,但是在里面显示各个行。限制2,我的意思是我想要两组。 (基本上不在表格中,获取右侧id的最后两个(最早到今天)的值组

3 个答案:

答案 0 :(得分:1)

有多种方法可以获得指定的结果集。

当我理解你的要求时,用不同的词重述规范:你想从表中找到第二高(不同)timeIn值(对于给定的r_id值) ,然后您希望返回表中的所有行(对于给定值r_id),其timeIn值大于或等于第二高timeIn值。按"设置",表示具有匹配的r_idtimeIn值的行集合。 (我完全有可能误解了规范。)

这是获取指定行的一种方法:

SELECT d.value
     , d.timeIn
     , d.r_id
  FROM mytable d
 WHERE d.r_id = 76703
   AND d.timeIn >=
       ( SELECT MAX(m2.timeIn) AS m2_timeIn
           FROM mytable m2
          WHERE m2.r_id = 76703
            AND m2.timeIn < 
                ( SELECT MAX(m1.timeIn) AS m1_timeIn
                    FROM mytable m1
                   WHERE m1.r_id = 76703
                )
       )
 ORDER BY d.timeIn DESC, d.value ASC

注意

此查询的性能取决于具有 r_id timeIn 的前导列的索引,因为等式谓词和范围扫描。

... ON mytable (r_id, timeIn, ... )

EXPLAIN将显示计划中的步骤。 MySQL应首先运行最内层的查询,以获得第一个最高timeIn值。然后,MySQL应该针对m2运行查询,以获得第二高的timeIn值。将其作为常量,MySQL应该针对d运行查询以获取...


<强>后续

此外,文字76703的谓词位于外部查询和子查询中也很重要。 (那里有诱惑将它们变成相关的子查询,用高级查询中的引用替换文字......但出于性能考虑,你不想这样做(因为MySQL处理的方式)相关的子查询。)你不会注意到小集合上的问题,但是对于较大的集合,性能损失会变得明显,并且对于大集合,性能变得难以忍受。

为了获得两个最高的值,MAX(foo) WHERE foo < (SELECT MAX(foo)方法可能是最有效的。显然,这可以扩展到三,四等。

但要获得百分之一的最高值,SQL就变得笨拙了。

获取 n 最高值的另一种方法是使用类似这样的查询:

SELECT mn.timeIn
  FROM mytable mn
 WHERE mn.r_id = 76703
 GROUP BY mn.timeIn
 LIMIT n-1 ,1

其中 n-1 代表&#34;最高&#34;您想要跳过的值。 (例如,要获得第10个最高值,请指定LIMIT 9,1。)

请注意,如果至少没有&#34; n&#34; timeIn的不同值,此查询不会返回一行(对于第一个查询中使用的方法也是如此。)

答案 1 :(得分:0)

您可以执行以下操作:

 Select * from db.table t
 where t.r_id = 76703
 AND timeIn >= (select distinct timeIn from db.table t
                WHERE r_id = 76703  
                ORDER BY timeIN desc LIMIT 1, 1)

子查询从唯一的timeIns中按降序选择第二个项目,外部查询选择timeIn大于或等于该记录的所有记录。

答案 2 :(得分:-1)

这可能有用......

   select * from db.table t
   where timeIn<=select timeIn from db.table order by  timeIn DESC limit 1 
        or
        time>=(select timeIn from db.table 
              where time<(select timeIn from db.table order by  timeIn DESC limit 1) 
              order by  timeIn DESC limit 1