MySQL:连接表重复SUM()

时间:2016-11-18 11:34:51

标签: php mysql join sum left-join

我正在与一个处理产品的双语网站合作。

每件商品都有skusupplier_id。插入产品时,如果sku supplier_id已经存在,而不是创建新产品,我只需更新其数量。

如果只有sku匹配,但supplier_id不同,那么我会创建一个新产品。

由于网站是多语言,因此有一些翻译表。

当我搜索产品时,我会为每个sku显示一个,将数量相加。

这是我的查询

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

有两种不同的产品具有相同的sku,一种产品的数量为5,另一种产品的数量为2.

quantity字段应该返回7,而不是返回9.基本上,第二个产品是重复的。

删除LEFT JOIN products_locale locale ON (products.id = locale.product_id AND locale.language_code = 'it')可以解决问题,但我需要该字段。

更奇怪的是,我加入了两个转换表,products_localeapp_categories_locale,但只有products_locale会导致此行为。

有没有办法检索相同的字段而不重复行?

谢谢

2 个答案:

答案 0 :(得分:1)

  1. 当你有WHERE条件产品时,你真的需要阅读products.slug.slug =' slug&#39 ;?我的意思是,无论如何,你只能获得有价值的行' 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
    

    现在,您将此笛卡尔积分组并计算总和。你必须知道,如果它是正确的, 一种产品在一种语言中有多个描述。它可能是错的 您的应用程序的业务视图。在这种情况下,您只需要修复"你的数据库。

    如果您的数据正确无误,则需要单独对products进行分组。类似的东西:

    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 ...
    

    但是,然后,并且还使用了viki888中的sql,在同一个sku的结果中将得到2行,但是, 正确的总和7,并有不同的描述。

  3. 我想知道,如果你的选择甚至运行,因为在分组时,你只能选择属性,你要分组(加上其余属性的聚合函数)。由于您按sku分组,在1个相同sku值的组中,您可以获得多个产品。因此,即使您对每种产品只有一种描述(1种语言),您也试图将一组产品附加到产品组中,但是哪一种?它没有任何意义,并且sql也应该在执行时崩溃。

  4. 尝试总结一下,您打算做什么,并提供一些示例数据(products_locale的内容,products的内容和您想要的结果)

答案 1 :(得分: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')

希望这可以解决你的问题。