webdevqa.jp.net

only_full_group_byでクエリグループを修正する方法

基本的なKey-Valueテーブルがあり、ユーザーごとにいくつかのデータが含まれています。更新されたmysqlでは、group byを実行すると、sql_modeonly_full_group_by(新しいデフォルト)に設定されます。この単純なクエリを実行しようとすると、次のようになります。

select * from user_features
where user_id = 1
group by feature_key

次のエラーが発生します。

SQLエラー(1055):SELECTリストの式#1がGROUP BY句になく、GROUPBY句の列に機能的に依存しない非集約列 'date.user_features.user_id'が含まれています。これはsql_mode = only_full_group_byと互換性がありません

このサンプルデータでは、feature_keyに基づいてグループ化します(グループエラーが修正されたら、group_concatを追加します)。

| user_id | feature_key | feature_value |
+---------+-------------+---------------+
| 1       | color       | red           |
+---------+-------------+---------------+
| 1       | age         | 15            |
+---------+-------------+---------------+
| 1       | color       | blue          |
+---------+-------------+---------------+

テーブルは次のようになります。

CREATE TABLE `user_features` (
  `user_id` int(10) unsigned NOT NULL,
  `feature_key` varchar(50) NOT NULL,
  `feature_value` varchar(50) NOT NULL,
  UNIQUE KEY `user_id_feature_key_feature_value` (`user_id`,`feature_key`,`feature_value`)
)

これを修正するためにどのクエリを実行できますか、またはどのインデックスを追加する必要がありますか?

5
Get Off My Lawn

これは、MySQLユーザーによくあるエラーです。 MySQL 5.7では、デフォルトで、データベースは他のほとんどのSQLデータベースが何年にもわたって実施してきた標準的なセマンティクスを実施します。

ルールは、選択リストのすべての列が次のいずれかである必要があるということです。

  • GROUPBY句で指定されています。つまり、それはあなたがグループ化しているものです。
  • MIN、MAX()、SUM()、GROUP_CONCAT()などの集計関数の内部。
  • グループ化する列に機能的に依存します(これはMySQLの標準SQL動作への拡張であり、他のSQLデータベースは必ずしもこれをサポートしていません)。

クエリで(_SELECT *_を展開します):

_select user_id, feature_key, feature_value from user_features
where user_id = 1
group by feature_key
_

Feature_keyでグループ化していますが、これは、他の列が上記のルールに準拠していないことを意味します。

これを修正する方法は次のとおりです。

_select MAX(user_id), feature_key, GROUP_CONCAT(feature_value)
from user_features
where user_id = 1
group by feature_key
_

WHERE句の条件に基づいて可能な値は1つしかないため、MAX(user_id)を使用するのは冗長に思えるかもしれません。しかし、害もありません。 MIN(user_id)も機能します。

この同じエラーに関する私の過去の回答も参照してください。

12
Bill Karwin