web-dev-qa-db-ja.com

MySQL:GROUP BYにはありません

サイトは結果を生成しますが、SELECT COUNTと、2つの異なる結果カウントを持つGROUP BYを使用したSELECTクエリを使用します。これは、サイトではなくphpmyadminに表示されるエラーが原因である可能性があります。

クエリ:

SELECT count(DISTINCT `name`) as `numrows` FROM `users` WHERE `verified` = '1'

SELECT `name`, `type`, `language`, `code` FROM `users` WHERE `verified` = '1' GROUP BY `name` ORDER BY `count` DESC LIMIT 0, 25

PhpMyAdminは次のエラーを提供します。

1055-'main.users.type'はGROUP BYにありません

MySQLのドキュメントを読んでいるとき、修正する必要があるものがまだわかりません。これを把握できないようです。

18
James Cordeiro

完全なグループが必要です:

SELECT `name`, `type`, `language`, `code` 
FROM `users` 
WHERE `verified` = '1' 
GROUP BY `name`, `type`, `language`, `code` 
ORDER BY `count` DESC LIMIT 0, 25

SQL92では、select句のすべての列(集計を除く)がgroup by句の一部である必要があります。 SQL99はこの制限を少し緩め、select句のすべての列がgroup by句に機能的に依存している必要があると述べています。 MySQLはデフォルトで部分的なグループ化を許可し、これにより非決定的な回答が生成される場合があります。例:

create table t (x int, y int);
insert into t (x,y) values (1,1),(1,2),(1,3);
select x,y from t group by x;
+------+------+
| x    | y    |
+------+------+
|    1 |    1 |
+------+------+

つまりランダムなyがグループxに対して選択されます。 @@ sql_modeを設定することにより、この動作を防ぐことができます。

set @@sql_mode='ONLY_FULL_GROUP_BY';
select x,y from t group by x; 
ERROR 1055 (42000): 'test.t.y' isn't in GROUP BY
32
Lennart

この問題の最善の解決策は、もちろん、完全な_GROUP BY_式を使用することです。

しかし、_ONLY_FULL_GROUP_BY_への古いMySQL拡張の_GROUP BY_ブロックを回避する別のソリューションがあります。

_SELECT name, 
       ANY_VALUE(type) type,
       ANY_VALUE(language) language,
       ANY_VALUE(code) code 
  FROM users  
 WHERE verified = '1' 
 GROUP BY name 
 ORDER BY count DESC LIMIT 0, 25
_

ANY_VALUE()は、MySQLの不完全な_GROUP BY_操作で暗黙的に使用されていたものを明示的に宣言します。サーバーは、返される任意の値を選択できます。

9
O. Jones

まず、なぜそうなのかを確認します。以前のバージョンでは、少し怠慢になることがありました:グループ化された列の値は結果に完全にリストされます(例外なしでそれぞれ1つ)が、他の選択された列の値は多かれ少なかれ省略されます-しかし、コードは't(したくない)をあなたに代わって教えてください:

- Hey, MYSQL, list the families of the street - but add a first name as well to every row.
- Okay sir, but shall I use the father's or the mother's or...? I'm a machine, give exact orders!

理由がわかったので、他の列に関する設定があるかどうかを判断できます。つかいます

MAX() AS
MIN() AS
etc, works with strings, too

またはそれが本当にすべて同じ場合、例えばグループ化された値に関連する非集計値に違いはありません。

ANY_VALUE() AS

いずれにせよ、「曖昧」であることを認識していることをmysqlに知らせますが、グループ化した列以外のすべての列に焦点を合わせたくないのです。

0
Szél Lajos

上記の複数回言及された別の解決策は、その迷惑な 'ONLY_FULL_GROUP_BY'をオフにすることです。この投稿のように: Disable ONLY_FULL_GROUP_BY

プロジェクト全体を数時間リファクタリングしたくない場合、このソリューションは非常に役立つと思います。そして、GROUP BYのリストではない列の予測不可能な値を気にしない場合。

0
Juri Sinitson