次の表があります。
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になります。
id
=同じotheridentifier
フィールドを持つ最新のレコードがあるため、3はスキップされます。
これが私がやろうとしたことです:
SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3
しかし、期待どおり、5、4、2ではなく、id
= 5、、および1の行を取得することになります。
誰かがこのクエリがなぜ私が期待したものを返さないのか教えてもらえますか? ORDER BYをASCに変更してみましたが、これは返された行を1、3、5に再配置するだけです。
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
テーブル自体を結合して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
同様の要件がありましたが、より高度な選択基準がありました。他のいくつかの回答を使用すると、必要なものを正確に取得できませんでしたが、次のようにGROUP BYとORDER BYを実行できることがわかりました。
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t
GROUP BY t.otheridentifier
SELECT * FROM table t1
WHERE t1.time =
(SELECT MAX(time) FROM table t2
WHERE t2.otheridentifier = t1.otheridentifier)
Andomarの回答 は、サブクエリを使用しないという点でおそらく最良です。
別のアプローチ:
select *
from `table` t1
where t1.`time` in (
select max(s2.`time`)
from `table` t2
group by t2.otheridentifier
)
このクエリを使用して正しい答えを得ることができます:
SELECT * FROM
(SELECT * FROM `table` order by time DESC)
t group by otheridentifier
どうですか
SELECT *, max(time) FROM `table` group by otheridentifier
これもまた:
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.