8

假设我有一个类似于以下的表:

Item         Description            Time
-----        -----------            -----
ItemA1       descript               08-16-2013 00:00:00
ItemA2       descript               08-16-2013 00:00:00
ItemA3       descript               08-16-2013 00:00:00
.
.
ItemAN       descript               08-16-2013 00:00:00

ItemB1       descript               08-13-2013 00:00:00
ItemB2       descript               08-13-2013 00:00:00
ItemB3       descript               08-13-2013 00:00:00
.
.
ItemBN       descript               08-13-2013 00:00:00
.
.
.
ItemX1       descript               01-13-2012 00:00:00
ItemX2       descript               01-13-2012 00:00:00
ItemX3       descript               01-13-2012 00:00:00
.
.
ItemXN       descript               01-13-2012 00:00:00

定期添加项目组。添加一组项目时,它们都添加了相同的“时间”字段。“时间”本质上用作该项目组的唯一索引。

我想选择具有第二高时间的项目组。在此示例中,我的查询应提取“B”项。我知道我可以做 max( time) 来选择“A”项,但我不知道我将如何做倒数第二个。

如果这意味着什么,我的“时间”列将存储为 TIMESTAMP。

4

10 回答 10

20

您可以尝试以下方法:

SELECT MAX(Time)
FROM yourTable
WHERE Time < (SELECT MAX(Time) FROM yourTable)

SQLFiddle Demo

于 2013-08-16T18:51:03.880 回答
7

一种方法:

SELECT t.*
 FROM mytable t
 JOIN ( SELECT l.time
          FROM mytable l
         GROUP BY l.time
         ORDER BY l.time DESC
         LIMIT 1,1 
      ) m
   ON m.time = t.time

这使用内联视图(分配了别名 m)来返回第二个“最大”时间值。GROUP BY 为我们提供了一个不同的列表, ORDER BY DESC 将最新的放在第一位,而“技巧”是 LIMIT,它返回第二行。LIMIT(m,n) = (跳过前 m 行,返回后 n 行)

使用该时间值,我们可以连接回原始表,以获取具有匹配时间值的所有行。


使用前导列为 的索引将提高性能time。(我认为 MySQL 应该能够避免“使用文件排序”操作,并相当快地从内联视图查询中获取结果。)

但是,在内联视图查询中包含谓词,如果您“知道”第二个最晚时间永远不会超过一定天数,则不会影响性能:

   WHERE l.time > NOW() + INTERVAL -30 DAYS

但添加后,查询将不会返回time超过 30 天前的“第二个最新”组。

获得第二个最新的SELECT MAX(time) WHERE time < ( SELECT MAX(time)方法(其他答案中给出的方法)可能会更快,特别是如果没有前导列的索引time,但性能最好通过实际测试来衡量。具有时间领先列的索引也将加速 MAX() 方法。)

LIMIT我提供的查询可以通过更改子句 ... LIMIT(3,1)LIMIT(41,1)等轻松扩展以获取最新的第 4、第 42等。

于 2013-08-16T18:51:58.863 回答
6

这应该给你第二大时间:

SELECT time FROM table GROUP BY time ORDER BY time DESC LIMIT 1,1
于 2013-08-16T18:57:27.310 回答
1
SELECT  T1.ITEM
FROM    YOURTABLE T1
WHERE   T1.TIME = ( SELECT  MAX(T2.TIME) 
                    FROM    YOURTABLE T2 
                    WHERE   T2.TIME < ( SELECT  MAX(T3.TIME) 
                                        FROM    YOURTABLE T3
                                    )
                )
于 2013-08-16T18:52:28.270 回答
1

使用以下查询获取第二、第三、第四......第 N 个最大值:

SELECT MIN(value) from yourTable WHERE value IN( SELECT TOP N value FROM yourTable ORDER BY value DESC)

将 N 替换为您的数字,即 N=2 表示第二高值,N=3 表示第三高值,依此类推。因此,对于第二高价值用途:

SELECT MIN(value) from yourTable WHERE value IN( SELECT TOP 2 value FROM yourTable ORDER BY value DESC)
于 2015-08-27T10:57:02.277 回答
0

像这样非常简单的东西应该可以工作

select * from my-table where time = 
  (Select top 1 time
     from (select top 2 time from my-table order by time desc)
   order by time asc)
于 2013-08-16T18:52:31.170 回答
0

这是我认为应该解决您的问题的另一种解决方案:

CREATE TEMPORARY TABLE xHighest AS (SELECT DISTINCT Time FROM `my-table` ORDER BY Time DESC LIMIT 1,1);

SELECT * FROM `my-table` JOIN xHighest ON (my-table.Time = xHighest.Time);

您可以通过更改 LIMIT 的第一个参数来选择是否应使用第二个、第三个、... 最大值。

于 2017-10-18T06:57:01.590 回答
0

MYSQL:限制基础解决方案

示例:记录 1、2、3、4、5。

LIMIT 2,1 表示它将返回第三大数字,因为 LIMIT 1,1 返回第二大数字,依此类推

选择 rc。rc_officer_idFROM recovery_complain_officer rc ORDER BY rc。rc_officer_idDESC 限制 2,1

于 2018-03-10T12:10:54.820 回答
0

Leftfield-ish 答案,但这允许您根据需要从单个表中选择 n-1 个有序值(归功于@Uueerdo 的https://stackoverflow.com/a/35234692/618320答案),几乎没有额外的成本。

您可以使用GROUP_CONCAT(DISTINCT...), 后跟一些SUBSTRING(...),

SELECT
  SUBSTRING_INDEX(groupTime, ',', 1) AS time1,
  SUBSTRING_INDEX(SUBSTRING_INDEX(groupTime, ',', 2), ',', -1) AS time2,
  SUBSTRING_INDEX(SUBSTRING_INDEX(groupTime, ',', 3), ',', -1) AS time3
FROM (
  SELECT GROUP_CONCAT(DISTINCT Time ORDER BY Time DESC) groupTime FROM mytable) t

内部查询会给你一个单行结果,如“08-16-2013 00:00:00,08-13-2013 00:00:00,01-13-2012 00:00:00”,然后拆分以我们正在做的方式串起来,给你一个表格结果,比如,

time1                 time2                time3
---------             ------------         ------------
08-16-2013 00:00:00   08-13-2013 00:00:00  01-13-2012 00:00:00
于 2018-05-10T15:24:54.060 回答
0

也许 TOP 和 START AT 可以在这里提供帮助。我在 Sybase SQL 中使用过它。

SELECT TOP 1 START AT 2 * FROM Table_Name ORDER BY CREATEDDATETIME DESC;

于 2019-07-30T15:30:08.497 回答