3

クエリに問題があり、mysql が次のエラーをスローします。

#1055 - Expression #66 of SELECT list is not in GROUP BY clause and 
contains nonaggregated column 's.status' which is not functionally 
dependent on columns in GROUP BY clause; this is incompatible with 
sql_mode=only_full_group_by

クエリは次のとおりです。

select   p.*,
pd.*,
m.*,
IF(s.status, s.specials_new_products_price, null) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
FROM products p 
LEFT JOIN specials s ON p.products_id = s.products_id  
LEFT JOIN manufacturers m using(manufacturers_id) , 
          products_description pd,
          categories c,
          products_to_categories p2c
WHERE p.products_view = 1  
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND p.products_id = pd.products_id
AND p.products_id = p2c.products_id
AND p2c.categories_id = c.categories_id
AND pd.language_id = 1

GROUP BY p.products_id;
4

4 に答える 4

15

GROUP BY を使用する場合、選択リストで式を使用できるのは、グループごとに 1 つの値を持つ場合のみです。そうしないと、あいまいなクエリ結果が得られます。

あなたの場合、MySQL はs.statusグループごとに複数の値を持つ可能性があると考えています。たとえば、グループ化してp.products_ids.statusますが、別の table の列でありspecials、おそらく table と 1 対多の関係にありますproductsspecialsそのため、同じで複数の行が存在する可能性がありますが、 のproducts_id値は異なりますstatus。その場合、statusクエリはどの値を使用する必要がありますか? あいまいです。

specialsデータでは、 の各行に対してに 1 つの行しかないように行を制限することがありますproducts。しかし、MySQL はその仮定を行うことができません。

MySQL 5.6 以前では、自分が何をしているのかを知っていると信じて、このようなあいまいなクエリを書くことができました。ただし、MySQL 5.7 では、デフォルトでより厳密な適用が有効になっています (以前のバージョンのように動作するように、これを緩和することができます)。

修正は、次の規則に従うことです。select-list のすべての列は、次の 3 つのケースのいずれかに該当する必要があります。

  • 列が COUNT()、SUM()、MIN、MAX()、AVERAGE()、GROUP_CONCAT() などの集計関数内にある。
  • 列は、GROUP BY句で指定された列の 1 つです。
  • GROUP BY列は、句で指定された列に機能的に依存しています。

詳細については、次の優れたブログを参照してください: Debunking GROUP BY myths


あなたのコメントについては、テーブル定義を投稿していないため、推測しかできません。

products_descriptionmanufacturersは機能的に に依存していると推測しているproductsので、選択リストにそのままリストしても問題ありません。しかし、この仮定は正しくないかもしれません。私はあなたのスキーマを知りません。

とにかく、s.status集計関数を使用してエラーを解決する必要があります。MAX()例として使用しています。

SELECT p.*,
pd.*,
m.*,
MAX(IF(s.status, s.specials_new_products_price, NULL)) 
  AS specials_new_products_price,
MAX(IF(s.status, s.specials_new_products_price, p.products_price)) 
  AS final_price
FROM products p 
LEFT OUTER JOIN specials s ON p.products_id = s.products_id  
INNER JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id
INNER JOIN products_description pd ON p.products_id = pd.products_id
INNER JOIN products_to_categories p2c ON p.products_id = p2c.products_id
INNER JOIN categories c ON p2c.categories_id = c.categories_id
WHERE p.products_view = 1  
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND pd.language_id = 1
GROUP BY p.products_id;

また、適切な方法で結合を書き直しました。コンマ形式の結合は避ける必要があります。

于 2016-08-01T18:26:46.450 に答える
1

しようとしていORDER BYますか?句は、句にさらに列を追加しない限り、句GROUP BYの列の個別の値ごとに 1 つの行を返そうとします。GROUP BY句に含まれていない他の非集計列があるため、エラーがスローされています。集計列はMAX(p.products_id)orのようなものになりますSUM(p.products_price)。クエリには、同じ p.product_price と異なる s.status 値を持つ複数の行があるため、GROUP BY意味がありません。

MySQL グループ処理: https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html 集計関数: http://dev.mysql.com/doc/refman/5.7/en /group-by-functions.html

于 2016-08-01T18:29:53.180 に答える
0

s.status 列に ANY_VALUE() 組み込み関数の使用を強調する人がいない理由がわかりません。

これをチェックしてください:https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions .html#関数_任意の値

于 2020-07-20T07:45:04.743 に答える