45

我有下表:

    id       time      text      otheridentifier
    -------------------------------------------
    1        6         apple     4
    2        7         orange    4
    3        8         banana    3
    4        9         pear      3
    5        10        grape     2

我想要做的是选择 3 个最近的记录(按时间降序),它们的otheridentifiers 是不同的。所以在这种情况下,结果将是id's: 5、4 和 2。

id= 3 将被跳过,因为有相同otheridentifier字段的更新记录。

这是我试图做的:

SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3

但是,我最终得到了id= 5, 31的行,而不是预期的 5, 4, 2 。

有人能告诉我为什么这个查询不会返回我所期望的吗?我尝试将 ORDER BY 更改为 ASC,但这只是将返回的行重新排列为 1、3、5。

4

8 回答 8

34

它不会返回您期望的结果,因为分组发生在排序之前,正如 SQL 语句中子句的位置所反映的那样。不幸的是,你将不得不变得更漂亮才能获得你想要的行。试试这个:

SELECT *
FROM `table`
WHERE `id` = (
    SELECT `id`
    FROM `table` as `alt`
    WHERE `alt`.`otheridentifier` = `table`.`otheridentifier`
    ORDER BY `time` DESC
    LIMIT 1
)
ORDER BY `time` DESC
LIMIT 3
于 2009-05-29T05:24:09.170 回答
18

您可以自行加入表格以过滤最后一个条目otheridentifier,然后取其中的前 3 行:

SELECT last.*
FROM `table` last
LEFT JOIN `table` prev 
    ON prev.`otheridentifier` = last.`otheridentifier`
    AND prev.`time` < last.`time`
WHERE prev.`id` is null
ORDER BY last.`time` DESC 
LIMIT 3
于 2009-05-29T05:31:43.987 回答
4

我有类似的要求,但我有更高级的选择标准。使用其他一些答案我无法完全得到我需要的东西,但我发现你仍然可以像这样做一个 GROUP BY 和 ORDER BY :

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t 
GROUP BY t.otheridentifier
于 2013-04-30T15:14:05.417 回答
2
SELECT * FROM table t1 
WHERE t1.time = 
    (SELECT MAX(time) FROM table t2 
     WHERE t2.otheridentifier = t1.otheridentifier)
于 2009-05-29T05:31:27.963 回答
2

Andomar 的答案可能是最好的,因为它不使用子查询。

另一种方法:

select *
from   `table` t1
where  t1.`time` in (
                    select   max(s2.`time`)
                    from     `table` t2
                    group by t2.otheridentifier
                    )
于 2009-05-29T05:43:33.257 回答
2

您可以使用此查询获得正确答案:

SELECT * FROM 
      (SELECT * FROM `table` order by time DESC)
          t group by otheridentifier
于 2014-01-08T06:23:45.320 回答
1

关于什么

SELECT *, max(time) FROM `table`  group by otheridentifier
于 2012-02-29T06:19:02.700 回答
0

这也是:

SELECT * FROM
OrigTable T INNER JOIN 
( 
SELECT otheridentifier,max(time) AS duration
FROM T
GROUP BY otheridentifier) S
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier.
于 2016-06-15T06:41:20.913 回答