🧮

[MySQL] ONLY_FULL_GROUP_BY

このオプションを有効にすると、GROUP BY した際、単一値の原則を満たさない行を選択リストに追加できなくなる。 ここで単一値の原則とは、選択リストに列挙するすべての列が行グループごとに単一の値を持たなければいけないというもの。

たとえば、記事の作者 (user_id) ごとにグルーピングする場合、公開日 (published_at) は行グループにおいて単一ではない (あるユーザが作成した記事は複数あり、公開日も複数存在する) ので、以下のクエリはエラーになる。

SELECT user_id, published_at
FROM posts
GROUP BY user_id

エラーを解消するには、たとえば次のようにする。 MAX(published_at) とすることにより、公開日は行グループにおいて単一の値となり、単一値の原則を満たす。

SELECT user_id, MAX(published_at) as latest
FROM posts
GROUP BY user_id

ほとんどの製品には ONLY_FULL_GROUP_BY オプションが存在せず、常にエラーを出力する。 このオプションが存在するのは、MySQL と SQlite だけである。 MySQL では行グループの最初の行、SQlite では最後の行が返されることになっている。 ただし、この仕様は文書化されておらず、将来のバージョンアップで変更される可能性があるので、この仕様を利用したクエリは書かないに越したことはない 🤔

ref. 『SQL アンチパターン』