Mysql

GROUP BY 使用 MIN() 聚合函式給出錯誤結果

  • February 26, 2020

我有一個看起來像這樣的表:

+------+--------+----------+------+--------+-------+------+------------+
| 編號 | 程式碼 | 類別 | MQ | 重量 | 編織 | 顯示 | 最低(價格) |
+------+--------+----------+------+--------+-------+------+------------+
| 1 | DT450R | 碳 | 1 | 450 | 平原 | 1 | 90 |
| 2 | DT450R | 碳 | 2 | 450 | 平原 | 1 | 40 |
| 3 | DT450R | 碳 | 5 | 450 | 平原 | 1 | 75 |
| 7 | PP120Q | 碳 | 3 | 120 | 斜紋| 1 | 28 |
| 8 | PP120Q | 碳 | 7 | 120 | 斜紋| 1 | 65 |
| 9 | PP120Q | 碳 | 9 | 120 | 斜紋| 1 | 49 |
| 4 | ZX300R | 碳 | 1 | 300 | 平原 | 0 | 12 |
| 5 | ZX300R | 碳 | 15 | 300 | 平原 | 1 | 128 |
| 6 | ZX300R | 碳 | 30 | 300 | 平原 | 1 | 92 |
+------+--------+----------+------+--------+-------+------+------------+

我在這裡創建了一個sqlfiddle

我想要每個程式碼中表格的最低價格。我嘗試使用以下查詢:

select id, code, category, mq, weight, weave, price, `show`, min(price) as total 
from product group by code;

為什麼組通過得到錯誤的結果?它正在返回id = 1而不是id =2.

輸出錯誤:

+------+--------+----------+------+--------+-------+------+------------+
| 編號 | 程式碼 | 類別 | MQ | 重量 | 編織 | 顯示 | 最低(價格) |
+------+--------+----------+------+--------+-------+------+------------+
| 1 | DT450R | 碳 | 1 | 450 | 平原 | 1 | 40 |
| 7 | PP120Q | 碳 | 3 | 120 | 斜紋| 1 | 28 |
| 4 | ZX300R | 碳 | 1 | 300 | 平原 | 0 | 12 |
+------+--------+----------+------+--------+-------+------+------------+

預期輸出:

+------+--------+----------+------+--------+-------+------+------------+
| 編號 | 程式碼 | 類別 | MQ | 重量 | 編織 | 顯示 | 最低(價格) |
+------+--------+----------+------+--------+-------+------+------------+
| 2 | DT450R | 碳 | 2 | 450 | 平原 | 1 | 40 |
| 4 | ZX300R | 碳 | 1 | 300 | 平原 | 0 | 12 |
| 7 | PP120Q | 碳 | 3 | 120 | 斜紋| 1 | 28 |
+------+--------+----------+------+--------+-------+------+------------+

作為一名 MySQL DBA,我很遺憾地承認 MySQL在其 SQL 處理方面可能相當隨意。其中最臭名昭著的壯舉之一就是它的GROUP BY行為。

例如,Aaron Bertrand 回答了為什麼我們在 SQL 查詢中使用 Group by 1 和 Group by 1,2,3?他將 MySQL 描述GROUP BYcowboy who-knows-what-will-happen grouping. 我只好同意了

建議

改寫GROUP BY使用code

select code,min(price) as total 
from product group by code

做三件事

  1. 使查詢成為子查詢
  2. 用作price別名而不是total
  3. 將其加入到產品表codeprice

這是建議的查詢

select b.* from
(select code,min(price) as price from product group by code) a
inner join product b using (code,price);

要麼

select b.* from
(select code,min(price) as price from product group by code) a
inner join product b ON a.code=b.code AND a.price=b.price;

為此簽出SQL Fiddle

試一試 !!!

更新 2017-01-06 16:17 EST

如果給定程式碼存在超過 1 行具有相同最低價格的行,則您已獲取查詢,使其成為子查詢,加入它以檢索每個 ( code, price) 的最小 id 並將其加入到productby id

select bb.* from
(select a.code,a.price,min(b.id) id from
(select code,min(price) as price from product group by code) a
inner join product b using (code,price)
group by a.code,a.price) aa
inner join product bb using (id);

為此檢查SQL Fiddle

引用自:https://dba.stackexchange.com/questions/160216