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

otheridentifier私がやりたいことは、 s が異なる3 つの最新のレコード (時刻の説明による) を選択することです。したがって、この場合、結果はid's: 5、4、および 2 になります。

idotheridentifier= 3 は、同じフィールドを持つより新しいレコードがあるためスキップされます。

これが私がやろうとしたことです:

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

ただし、期待どおりに 5、4、2 ではなくid= 5、3、および1の行を取得することになります。

このクエリが私が期待したものを返さない理由を誰か教えてもらえますか? 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

I had a similar requirement, but I had more advanced selection criteria. Using some of the other answers I couldn't get exactly what I needed, but I found you can still do a GROUP BY after and ORDER BY like this:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t 
GROUP BY t.otheridentifier
于 2013-04-30T15:14:05.417 に答える
2

このクエリを使用して正しい答えを得ることができます:

SELECT * FROM 
      (SELECT * FROM `table` order by time DESC)
          t group by otheridentifier
于 2014-01-08T06:23:45.320 に答える
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 に答える
1

どうですか

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