クエリは完全に合法的な構文であり、selectに存在しない列で並べ替えることができます。
法的な順序付けに関する完全な仕様が必要な場合、SQL Standard 2003には、順序付けに含めるべきものと含めないものに関するステートメントの長いリストがあります(02-Foundation、415ページ、セクション7.13 <クエリ式>、subパート28)。これにより、クエリが正当な構文であることが確認されます。
混乱は、group byに存在しない列の選択や順序付け、または個別の使用時にselectに含まれない列の順序付けから生じる可能性があると思います。
どちらも基本的な問題は同じであり、私の知る限り、どちらかを許可するのはMySQLだけです。
問題は、group byまたはdistinctを使用する場合、どちらにも含まれていない列は不要であるため、行全体で複数の異なる値が必要になることはないため、問題ではないということです。この単純なデータセットを想像してみてください:
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
3 | B | Y |
あなたが書く場合:
SELECT DISTINCT Column1
FROM T;
あなたが得るだろう
Column1
---------
A
B
次に、ORDER BY Column2
を追加すると 、AをXまたはZで注文するために、2つのcolumn2のどちらを使用しますか? column2の値を選択する方法については決定論的ではありません。
groupbyにない列の選択にも同じことが当てはまります。簡単にするために、前の表の最初の2行を想像してみてください。
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Z |
MySQLでは次のように書くことができます
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1;
これは実際にはSQL標準に違反しますが、MySQLで機能しますが、問題は非決定論的であり、結果は次のとおりです。
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
よりも多かれ少なかれ正しい
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
つまり、Column1
の個別の値ごとに1行を指定してください。 、両方の結果セットが満たすので、どちらを取得するかをどのようにして知ることができますか?そうではありませんが、ORDER BY
を追加して追加できるというのはかなり一般的な誤解のようです。 結果に影響を与える句。たとえば、次のクエリ:
SELECT ID, Column1, Column2
FROM T
GROUP BY Column1
ORDER BY ID DESC;
次の結果が確実に得られます:
ID | Column1 | Column2 |
----|---------+----------|
2 | A | Y |
ORDER BY ID DESC
のため ただし、これは正しくありません(ここに示されているように
。
MySQLドキュメント 状態:
したがって、これによる注文があっても、グループごとに1つの行が選択されるまで適用されず、この1つの行は非決定的です。
SQL-Standardでは、GROUP BYまたは集計関数に含まれていない選択リストの列を許可していますが、これらの列はGROUPBYの列に機能的に依存している必要があります。 SQL-2003-Standard(5WD-02-Foundation-2003-09-346ページ)から- http ://www.wiscorp.com/sql_2003_standard.zip
たとえば、サンプルテーブルのIDはPRIMARY KEYであるため、テーブル内で一意であることがわかっているため、次のクエリはSQL標準に準拠し、MySQLで実行され、現在多くのDBMSで失敗します(Postgresqlの執筆時点)標準を正しく実装するために私が知っている最も近いDBMSです-
SELECT ID, Column1, Column2
FROM T
GROUP BY ID;
IDは行ごとに一意であるため、Column1
の値は1つだけです。 IDごとに、Column2
の値が1つ 各行に何を返すかについては、あいまいさはありません。