GROUP BY
で機能しない理由
SELECT *
GROUP BY
では使用できません;無効なSQLです。 GROUP BY
テーブルの行を選択しません。提供された式を使用して行のグループを作成し、各グループから新しいレコードを生成し、式に含まれる値を使用してこの新しいレコードの各列を計算します。
SELECT
に表示される列 句は、次のいずれかのルールを満たす必要があります。
-
GROUP BY
にも表示されます 条項; - は
GROUP BY
集計関数 ; -
GROUP BY
に表示される列に機能的に依存します 条項。
*
は、クエリで使用されるテーブルのすべての列名のショートカットです。クエリの場合は、user
のみです。 列は上記の要件の1つを満たしています。
バージョン5.7.5より前
MySQLは上記の3番目のルールを実装していません。 SELECT
に含まれるクエリを受け入れるために使用されていました GROUP BY
のいずれにも従わない句の列 要件。このような列のクエリによって返される値は、不確定でした。
。
バージョン5.7.5以降、MySQLはGROUP BY
を拒否します 要件を満たしているクエリ。
ソリューション
いずれにせよ、問題の解決策にはGROUP BY
は含まれません。 。 LEFT JOIN
を使用して簡単に実行できます 正しい条件で:
SELECT lc.*
FROM comments lc # 'lc' from 'last comment'
LEFT JOIN comments nc # 'nc' from 'newer comment'
ON lc.user = nc.user # both comments belong to the same user
AND lc.id < nc.id # 'nc' is newer than 'lc'
WHERE nc.id IS NULL # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10
仕組み
テーブルに参加しますcomments
、別名lc
(ユーザーの「最後のコメント」からの「lc」)それ自体に対して、別名nc
(「新しいコメント」からの「nc」)。 join句は、lc
の各エントリと一致します nc
のすべてのエントリ 同じユーザーに属するもの(lc.user = nc.user
)および新しい(lc.id < nc.id
; IDは順番に割り当てられ、新しいコメントのid
の値は大きいと想定しました。 。
LEFT JOIN
の使用 lc
のすべての行が nc
に一致する行が見つからない場合でも、結合の結果にが表示されます (同じユーザーの新しいコメントがないため)。この場合、NULL
nc
のフィールドの代わりに使用されます 。 WHERE
句は、NULL
を持つ行のみを最終結果セットに保持します nc.id
内;これは、lc
で意味します 一部には、各ユーザーの最新のコメントが含まれています。
SELECT
句には、lc
のすべてのフィールドが含まれます (nc
のもの すべてNULL
です 、 とりあえず)。 ORDER BY
句を使用して、結果セットを並べ替えることができます。 ORDER BY lc.id DESC
最新のコメントを最初に配置し、LIMIT
句は、結果セットを適切なサイズに保ちます。