:元公式ハンドブックからのMySQL 5.7 のMySQL BY GROUPの12.20.3取扱い
SQL-92およびそれ以前のバージョンでは、GROUP BY句で指定されていない非ポリマー列のリストを参照する照会BY条件またはORDERをHAVING、SELECTリストを許可していません。それは、次のクエリが禁止され、次のとおりです。
SELECT o.custid、c.name、MAX (o.payment) FROM注文AS、顧客O AS C WHERE o.custid = c.custid GROUP BY o.custid。
そのような名前とお客様IDとの間に存在する場合 - SQL-1999およびより高いオプションとして、このようなクエリを許可し、関数に(それらが列BY GROUPに機能的に依存している場合)、これらの列は、列のGROUP BYに依存することを条件とします関係は、クエリは、例えばお客様IDは、の主キーの顧客である、合法です。
MySQLの5.7.5以降の機能に依存する検出を実現。ONLY_FULL_GROUP_BY SQLモードは(デフォルト)有効になっている場合、MySQLはリストBY条件またはORDERを持つ、選択に記載されているかを拒否します、GROUP BY句での参照がありますという名前でもなく、その非機能的に依存してもされていません集計列。
5.7.5前に、MySQLは機能的依存性を検出しない、ONLY_FULL_GROUP_BYはデフォルトで有効になっていません。(不思議私はデフォルトが開いていない、5.7.21ませんでした。)
それはONLY_FULL_GROUP_BYが有効でない場合、MySQLは以前のクエリことを受け入れなければならないでしょう。この場合、サーバは、これはあなたが望むものではないかもしれないが、彼らは、同じでない限り、そうでない場合は、選択した値が不確定であるので、各グループ内の値のいずれかを自由に選択することができます。
さらに、ORDER BY句は、グループごとに選択された値に影響を及ぼさない添加します。ソートアウト設定値を選択した後に発生し、そうBY ORDERは、サーバは、各グループ内の値を選択した方法には影響しません。
あなたは、いくつかの属性データを知っているように、各グループのGROUP BY内の各非ポリマー無名列のすべての値が同じです。この禁止でONLY_FULL_GROUP_BYは有用である可能性があります。
以下の議論は、MySQLの機能不足している依存関係が発生し、MySQLは道に関数依存性が欠落しているクエリを受け入れることができるように関数依存性だけでなく、エラーメッセージが表示されます。
ONLY_FULL_GROUP_BYモードでは、次のクエリでは違法となる場合があります。
SELECT名前、住所、MAX(年齢)FROMトンのGROUP BY名。
名前は、主キーのトンである、または名前がユニーク、NOT NULLでフィールドである場合は、クエリは、法的になります。この場合、MySQLは機能的な依存関係のクエリー列アドレスと列グループを認識します。例えば、一つの行ように、各グループは、1つのプライマリキーを持っているので名前は、プライマリ・キーは、その値決定されたアドレス値である場合。そのため、グループアドレス値のMySQLの選択はランダム性を持っていないだろう、それはクエリを拒否する必要はありません。
名前は、主キーをtはないか、名前がユニークな、NOT NULLのフィールドでない場合は逆に、この場合には、MySQLが機能的依存性を推測することができないため、問合せは、違法であり、エラーが発生します。
ERROR 1055(42000):式#2 の SELECTリストがある しない で GROUP BY節および 含有非凝集カラム 「mydb.t.address 」ではない機能的依存に列にGROUP BY 節を、これは、 ある非互換で sql_modeの= ONLY_FULL_GROUP_BY
あなたがそのMySQLのクエリを受け入れなければならない場合は、ANY_VALUE()関数を使用することができます。
SELECT名前、ANY_VALUE(アドレス)、MAX(年齢)FROMトンのGROUP BY名。
もちろん、増幅され動きがONLY_FULL_GROUP_BYモードを禁止しました。
しかし、ここでの例は非常に簡単です。各グループは一つだけの行を含んでいるので、特に、我々は、単一の主キー列にグループ化されにくいです。他の例は、より複雑なクエリでは、「関数従属性」を立証するために、12.20.4を参照。
選択クエリは、集計関数が、GROUP BY句がないが含まれている場合。そして、ONLY_FULL_GROUP_BYモードでは、リストは非ポリマーを含んでいる列BY ORDERリスト句、HAVING条件を選択することはできません。次のように:
/ * sql_modeの= ONLY_FULL_GROUP_BY * / mysqlの> SELECT名前、MAX(年齢)FROM T; ERROR 1140(42000):で集約クエリせずGROUP BY 、式 #1 の SELECTリストが含まれている非凝集列 ' mydb.t.nameを' 。これは、 ある非互換で sql_modeの= ONLY_FULL_GROUP_BY
GROUP BY句が存在しない場合は、このグループになるように選択された名前を決定されていないが、一つのグループだけが、そこにあります。名前のMySQLの選択の値が無関係である場合この場合、ANY_VALUE()は便利になることができます。
/ * エラーなし* / SELECT ANY_VALUE(名)、MAX(AGE)FROM T。
MySQLの5.7.5およびそれ以降では、ONLY_FULL_GROUP_BYもクエリBY DISTINCTを使用してORDERに影響を与えます。
以下を含む3 C1、C2、C3のテーブルTを有すると仮定されます。
/ * C1 C2 C3 1 2 A 3 B 4 1 2のC * /
我々は、C3の列でソートされた期待した結果が次のクエリを実行したとします
SELECT DISTINCT C1、C2 FROMトンのORDER BY C3を。
結果をソートするには、最初に重複を削除する必要があります。しかし、これを行うには、我々は最初の行または三行目を保つ必要がありますか?この任意選択は、任意の並べ替えを持って、ソートに影響を与える順番にC3、C3と保持の保持に影響を与えます。
表現BY任意の順序は、クエリBY DISTINCTとORDERが無効として拒否されますが、以下の条件のうちの少なくとも1つを、満たしていない場合は、この問題を回避するには:
- 選択リストに等しい式。
- すべては、クエリの発現一部と、選択したテーブルの列を引用し、中国のリストのすべての要素を選択します
MySQLは他の標準SQLに対する拡張です:句を持つSELECT句という別名で参照可。
たとえば、次のクエリは、名前の値がライン一度表示されますが返されます。
SELECT名前、COUNT(名前)FROM 注文 GROUP BY 名 HAVING COUNT(名前)= 1。
しかし、次のようにMySQL拡張後に使用することができます。
SELECT名前、COUNT(名前)AS C FROM 注文 GROUP BY 名 HAVING C = 1。
注:MySQLの5.7.5より前、ONLY_FULL_GROUP_BYはこの拡張機能を無効にします有効にするには、HAVING句を書くために非エイリアスの式を使用する必要があります。
、私のノートの前面を押し句は、Select句の前に実行された、間違っているように見えますか?そうやって何も問題ないの私のバージョン(5.7.21)で、ビット実験(何を、コンパイルして順序関係を推測します?):
選択 SIDは、カウント(SID)をとして N から SCのグループ によって SIDが有する N = 3 。 / * + ------ + --- + | SID | N | + ------ + --- + | 01 | 3 | | 02 | 3 | | 03 | 3 | | 04 | 3 | + ------ + --- + * /
また、BY句の標準的なSQLのGROUPで、言及することができる唯一の列式(列式)許可され、およびFLOOR(値/ 100)がnoncolumn式(noncolumn式)であるため、そのため、ステートメントが無効である必要があります。
SELECT ID、FLOOR(値/ 100 ) FROM tbl_nameをの GROUP BY ID、FLOOR(値/ 100)。
MySQLはこれを拡張して、上記の文は有効です。
標準SQLには、GROUP BY句は、MySQLが許可されているエイリアスを、表示されたことはできません。したがって、上記のクエリに変更することができます:
SELECT ID、FLOOR(値/ 100)AS ヴァル FROM tbl_nameをの GROUP BY ID、ヴァル。
これは、valの列式と考えられています。
非列式がGROUP BYに表示されたら、MySQLは表現や表現の選択句リストの間で平等を認識しています。これはONLY_FULL_GROUP_BY SQLモード有効になっているが、ID、GROUP BYが含まれている意味、FLOOR(値/ 100)クエリが同じFLOOR()式を選択リストがあったため、有効です。
しかし、MySQLは非列式(関数依存性)に依存する関数、GROUP BYを特定しようとしないので、あなたはONLY_FULL_GROUP_BYを有効にすると、次のクエリでは、3番目の式の選択リストは、ID列のための簡単な式であっても、有効ではありません:IDそしてFLOORでGROUP BY()が追加されます。(すなわち、ID + FLOOR(値/ 100)とカラムBY GROUPは、従属関数存在しません)
SELECT ID、FLOOR(値/ 100)、ID + FLOOR(値/ 100 ) FROM tbl_nameをの GROUP BY ID、FLOOR(値/ 100)。
ソリューションは、派生テーブルを使用することです:
SELECT ID、F、ID + Fを FROM (SELECT ID、FLOOR(値/ 100)AS F FROM tbl_nameをの GROUP BY ID、FLOOR(値/ 100))AS DT。