2016-08-01 20 views
1

、GROUP BYではありません、私は私のクエリとMySQLとの問題を抱えているが、次のエラーがスローされます。MySQLのエラー:SELECTリストは句

#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; 

答えて

11

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

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

データでは、行ごとにspecialsの1つの行のみを持つように行を制限すると、productsになることがあります。しかし、MySQLはその前提を作ることはできません。

MySQL 5.6以前では、あいまいなクエリを書くことができます。しかし、MySQL 5.7では、デフォルトでより厳格な強制が可能になります(これは、以前のバージョンと同じように動作することがより厳しくできます)。

修正は、この規則に従うことです:列がCOUNTなどの集計関数内で

  • ()、SUM()、MIN:あなたの選択リスト内のすべての列は3例いずれかに該当しなければなりません、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; 

また、適切な方法で結合を書き直しました。コンマスタイルの結合は避けるべきです。

+1

私にそれを打つ!素晴らしい説明も。 –

+0

私はSQL_CALC_FOUND_ROWS s.products_idを選択するか、SQL_CALC_FOUND_ROWS count(p.products_id)を選択するかのように異なる方法で試しましたが、解決策はありませんこれを書き直す考えですか? – kurama

+0

@kuramaグループ化している列を集計しようとしています。 Billが説明しているように、選択リストに含まれる他の列が 'GROUP BY'節に含まれているか、集約されているか、グループ化された列に依存してグループ化が正しく機能するようにする必要があります。たとえば、 'p.products_id、s.status、sum(p.products_price)、...をp.products_id、s.status'によってプロダクトpグループから選択します。 –

1

ORDER BYをしようとしていますか? GROUP BY句は、句に列を追加しないかぎり、GROUP BY句の列の異なる値ごとに1つの行を返そうとします。この句に含まれていない他の集約されていない列があるため、集計された列はMAX(p.products_id)または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

0

あなたが特定の列にGROUP BYを使用して、結果のIDを取得したい場合は、それを行うにはどのように1つの素敵なトリックがある:

SELECT `distinct_column`, MAX(`id`), MAX(`another_int_column`) FROM `table_name` GROUP BY `distinct_column` 

結果:

distinct_column id  another_int_column 
Abertamy   13579 11 
Adamov   17765 14 
Adolfovice  2924  3 
Achotín   2241  2 
Babice   17772 14 

は今、あなたはdistinct_columnとWiは異なる値を持っていますそれに対応する行の値。

source

私はidとanother_int_columnは一意でなければならないと思いますが、私はよく分かりません。

関連する問題