2016-11-18 47 views
5

任務:向每個商店顯示購買量最高的產品。
3桌:商店,產品,付款。如果銷售給1個商店的產品有捆綁,那麼挑選哪個產品並不重要,只需選擇其中一個。MySQL分組問題:與sql_mode = only_full_group_by不兼容

我對這個查詢有一組問題的條款:

SELECT shop_id, product_id, 
(
    SELECT COUNT(*) 
    FROM payment 
    WHERE product.product_id = payment.product_id 
) sold 
FROM product 
GROUP BY shop_id 
HAVING MAX(sold) 

在MySQL 5.6或降低此查詢會工作。 這將是其結果是正確的:

shop_id | product_id | sold 
1   1   3 
2   3   1 
3   5   1 

但在5.7我越來越具有的sql_mode不兼容= only_full_group_by,因爲PRODUCT_ID在選擇包含非聚合數據。

完整的錯誤信息:

Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'product.product_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 

因此,我認爲會增加該組中的product_id解決方案通過像這樣:

SELECT shop_id, product_id, 
(
    SELECT COUNT(*) 
    FROM payment 
    WHERE product.product_id = payment.product_id 
) sold 
FROM product 
GROUP BY shop_id, product_id 
HAVING MAX(sold) 

修復該錯誤,但返回錯誤的結果,它不會使商店專欄變得獨一無二。我得到這個:

shop_id | product_id | sold 
1   1   3 
1   2   4 
2   3   1 
2   4   1 
3   5   1 

SQLfiddle使用MySQL 5.6,而是讓大家的生活更輕鬆:http://sqlfiddle.com/#!9/ca12bf9/6

+0

什麼是不明確的是爲什麼你在這裏使用支付表 – e4c5

+0

@ e4c5 1付款有1個產品,1個產品有0..N付款。支付表中的每一行代表一個已售出的產品,所以我就這樣做了一個計數器,因此我知道特定產品已售出多少次。 – Amodar

+0

我不確定原始結果是否正確,因爲從原始數據看來,shop_id 2每個產品3和4都銷售了1件。您希望如何處理聯繫?這是應該考慮的事情。 – CGritton

回答

3

你的要求是極其複雜的。你從MySQL的非標準擴展GROUP BY得到一個有用的結果是完全是偶然的。基於該擴展的結果與說話的驢不相像。它的功能不是很好,它的功能非常棒。

這就是你必須做的。

(1)按產品和商店總結銷售額。 (http://sqlfiddle.com/#!9/ca12bf9/12/0

    select product.product_id, product.shop_id, count(*) sale_count 
        from product 
        join payment on product.product_id = payment.product_id 
        group by product.product_id, product.shop_id 

(2),通過總結(1)(http://sqlfiddle.com/#!9/ca12bf9/13/0

 SELECT MAX(sale_count) max_sale_count, shop_id 
     FROM (
        select product.product_id, product.shop_id, count(*) sale_count 
        from product 
        join payment on product.product_id = payment.product_id 
        group by product.product_id, product.shop_id 
       ) findmax 
     GROUP BY shop_id 

(3)加入找到的在每個店的暢銷的產品銷售數量(1 )到(2)檢索每個商店中銷售量最高的產品的身份。(http://sqlfiddle.com/#!9/ca12bf9/11/0

SELECT a.product_id, a.shop_id, b.max_sale_count 
    FROM (
      select product.product_id, product.shop_id, count(*) sale_count 
       from product 
       join payment on product.product_id = payment.product_id 
      group by product.product_id, product.shop_id  
     ) a 
    JOIN (
     SELECT MAX(sale_count) max_sale_count, shop_id 
       FROM (
         select product.product_id, product.shop_id, count(*) sale_count 
         from product 
         join payment on product.product_id = payment.product_id 
         group by product.product_id, product.shop_id 
        ) findmax 
       GROUP BY shop_id 
     ) b ON a.shop_id = b.shop_id AND a.sale_count = b.max_sale_count 

您提供的數據有一條平行線。因此,兩種不同的產品在您的某個商店中顯示爲暢銷品。

這是一種將結構化的結構化爲結構化查詢語言的查詢。

1

要麼你可以通過設置sql_mode ='' in my.ini

設置的sql_mode爲空白 也可以使用ANY_VALUE(product_id)

同時對組使用非聚合列永遠不會保證結果是什麼。

https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value

更新1http://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

+0

謝謝,ANY_VALUE確實有效。但是,一定有辦法解決這個問題沒有ANY_VALUE或更改SQL模式? – Amodar

+0

在以前版本的mysql中,mysql隱含地執行與5.7中介紹的功能相同的行爲,您可以查看更多關於更新的答案 – developerCK

相關問題