2016-11-18 14 views
0

私は、製品を扱うバイリンガルなウェブサイトで働いています。MySQL:結合テーブルの複製SUM()

各製品は、skusupplier_idです。商品を挿入するときに、skusupplier_idが既に存在する場合は、新しい商品を作成するのではなく、その数量を更新するだけです。

skuが一致しますが、supplier_idが異なる場合は、新しい製品を作成します。

ウェブサイトは多言語であるため、翻訳のためのいくつかの表があります。

私が商品を検索するときには、それぞれskuの1つが表示され、数量が合計されます。

これは、同じskuを持つ2つの異なる製品があります。私のクエリ

SELECT 
    products.id, products.sku, products.slug, 
    SUM(products.quantity) quantity, 
    suppliers.name supplier_name, 
    locale.description, 
    categories.name category_name 
FROM products products 
    LEFT JOIN products_locale locale ON (products.id = locale.product_id AND locale.language_code = 'it') 
    LEFT JOIN app_suppliers suppliers ON products.supplier_id = suppliers.id 
    LEFT JOIN app_categories_locale categories ON (products.category_id = categories.category_id AND categories.language_code = 'it') 
WHERE products.slug = 'slug' 
GROUP BY products.sku 

あり、一つは数量5を持ち、もう一方は2

quantityフィールドは7を返す必要があり、その代わりに9を返します。基本的には、2番目の製品が複製されます。

LEFT JOIN products_locale locale ON (products.id = locale.product_id AND locale.language_code = 'it')を削除すると問題は解決しますが、そのフィールドが必要です。

さらに奇妙なことは、products_localeapp_categories_localeという2つの変換テーブルを結合しても、products_localeだけがこの現象を引き起こすことです。

行を複製せずに同じフィールドを取得する方法はありますか?

+0

あなたが、およびいくつかのサンプルデータを与える(products_localeの内容、productsの内容と、ご希望の結果)を目指しているもの、要約してみてください。 *を選択してグループを削除してみてください。これは、すべての行と、重複している行を明らかにする必要があります。それらを特定すると、クエリを更新するのが簡単になります –

+0

何を知りたいですか?グループを削除すると何も変わらず、*を選択すると何も変わりません。私が言ったように、その単一のLEFT JOINが問題です –

答えて

0

てみクエリの下に、これはあなたの問題を解決する必要があり

SELECT P.*, locale.description 
FROM ( 
    SELECT 
     products.id, products.sku, products.slug, 
     SUM(products.quantity) quantity, 
     suppliers.name supplier_name, 
     categories.name category_name 
    FROM products products 
     LEFT JOIN app_suppliers suppliers ON products.supplier_id = suppliers.id 
     LEFT JOIN app_categories_locale categories ON (products.category_id = categories.category_id AND categories.language_code = 'it') 
    WHERE products.slug = 'slug' 
    GROUP BY products.sku) P   
    LEFT JOIN products_locale locale ON (P.id = locale.product_id AND locale.language_code = 'it') 

希望をいただき、ありがとうございます。

+0

申し訳ありませんが、このクエリには何か構文が間違っています –

+0

何が問題になっていますか? – Viki888

1
  1. products.slugは、products.slug = 'slug'の条件を満たすときには、実際にproducts.slugを読む必要がありますか?つまり、値 'slug'の行しか取得できません。

  2. お使いの製品のテーブルには、

    ID | quantity | products.sku | ... 
    ---------------------------------- 
    1 | 5  |  sku1 
    2 | 2  |  sku1 
    ... 
    

    のように見えるかもしれませんし、products_localeは、あなたが最初に以下の になり、それらの関係のデカルト積を作成することを、

    product_id | description | language_code | ... 
    ------------------------------------- 
        1  | abc  |  it 
        2  | def  |  it 
        2  | xyz  |  it 
    ... 
    

    問題があるように見えるかもしれ表示:

    ID | quantity | products.sku | product_id | description | language_code | ... 
    ----------------------------------------------------------- 
    1 | 5  |  sku1  |  1  | abc  |  it 
    2 | 2  |  sku1  |  2  | def  |  it 
    2 | 2  |  sku1  |  2  | xyz  |  it 
    

    今yこのカルテシアン積をグループ化し、その合計を計算する。正しい場合は、 1つの製品に複数の説明が1つの言語で含まれていることを知っていなければなりません。アプリケーションのビジネスビューの から間違っている可能性があります。その場合、データベースを修復するだけで済みます。

    データが正しい場合は、productsを別々にグループ化する必要があります。ような何か:viki888からSQLを使用して

    SELECT * FROM 
        (SELECT id, sku, SUM(quantity) from products WHERE slug='slug' group by sku, id) p 
        LEFT JOIN products_locale l ON p.id=l.product_id  
        LEFT JOIN ... 
        LEFT JOIN ... 
    

    しかし、その後、また、あなたは 正しい合計7と、異なる説明では、しかし、同じSKUの結果で2行を取得します。

  3. あなたの選択が実行されていても、グループ化すると属性のみを選択でき、残りの属性の集約関数によってグループ化されるため、不思議です。 skuでグループ化しているので、同じグループの1つで、skuの値を取得すると、いくつかの製品が得られます。したがって、たとえ各製品の説明が1つだけ(1つの言語で)あったとしても、製品のグループに説明を1つ付けようとしていますが、どちらを記述しようとしていますか?それは何の意味もなく、実行時にsqlもクラッシュするはずです。

は、それが他のデータなしで言うのは本当に難しいです

関連する問題