DISTINCTとGROUPBYの両方を一緒に使用する次のMySQLクエリを見ました:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
クエリに沿ったシナリオは次のとおりです。各ユーザーには一意のID user_id
があり、一意のID
。各投稿にはテキストが含まれます。
(Oracle DBから来た後)これは紛らわしいと思い、以下の質問がありました:
-
GROUP BY
集計を行わずに?
-
SELECT
とGROUP BY
の列の順序を切り替えることの重要性は何ですか。 ?
-
GROUP BY
から3番目の列を省略するとはどういう意味ですか?
-
DISTINCT
はGROUP BY
と一緒に使用されますか?最終結果ですべてのグループ化が行われた後、またはその前に、個別の操作が実行されますか?
コメント
回答
ad 1)古いmysqlデータベースで、 ONLY_FULL_GROUP_BY を無効にすると、このクエリを実行できます。post_contentがすべて等しい場合は、mysqlが決定論的ではないランダムな値を返します。 。
ad 2)これまでにない
ad 3)怠惰なプログラミングであり、 ONLY_FULL_GROUP_BY を有効にすると、エラーが発生します。 a>
ad 4)いいえ、user_idに接続されているすべてのpost_contentが表示されます。post_idは、グループへのpost_contentの追加と同様です
Strawberryがすでに言っているように、このクエリは「理にかなっている
回答
古いバージョンのMySで部分的なgroupbyを許可する非常識な機能QLは、IT業界で最も引き起こされた混乱の1つのトップ候補である必要があります。
表を考えると:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
ステートメント
SELECT x, y FROM t GROUP BY x
は(1,1)または(1,2)を意味する可能性があり、MySQLはこれらのいずれかをランダムに返します。この場合、DISTINCTは重要ではなく、結果は依然として不確定です。
SQL92では、select句のすべての列(集約された列と定数を除く)がGROUPBY句の一部である必要があります。
SQL99はこの制限を少し緩和し、残りの列に機能的に依存するGROUPBYからの列を除外できるようにしました。つまり、
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
yはf.dなので、有効になります。 of x
(私にとって)驚くべきことに、SQL99バージョンの実装に関しては、MySQLの新しいバージョンがクラス最高です。最近チェックしていませんが、MySQLはかなり複雑なシナリオをうまく処理しましたが、PostgreSQLは些細なシナリオしか処理しませんでした。
質問に答える
1)
SELECT x, y FROM t GROUP BY x, y
は、x、yの組み合わせがグループであることを意味します。考えられるすべての状況で、これは次のように考えることができます。
SELECT DISTINCT x, y FROM t
論理的に異なる時間に評価されるため、実際には異なる場合があります(ただし、1つは考えられません)
2)なし、この点では、これらは列のセットであるため、順序はありません
3)上記を参照してください。
4)SQLクエリの評価の論理的な順序は次のとおりです。
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
したがって、GROUPBYはDISTINCTの前に評価されることになっています。これが問題になる状況は考えられません。
クエリで誰かが紛らわしい結果を得て、DISTINCTを使用して別の結果を取得しようとしたのではないかと思います。おそらく、結果を取得するのに幸運な(または不幸な)場所です。期待されたので、DISTINCTはとどまりました。バグはまだあります
GROUP BY
はまったく重要ではありません(古いバージョンでは、同じORDER BY
を意味していました。SELECT
順序は、出力の列の配置でのみ重要です。