Mysql
GROUP BY 使用 MIN() 聚合函式給出錯誤結果
我有一個看起來像這樣的表:
+------+--------+----------+------+--------+-------+------+------------+ | 編號 | 程式碼 | 類別 | 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 BY
為cowboy who-knows-what-will-happen grouping
. 我只好同意了。建議
改寫
GROUP BY
使用code
select code,min(price) as total from product group by code
做三件事
- 使查詢成為子查詢
- 用作
price
別名而不是total
- 將其加入到產品表
code
中price
這是建議的查詢
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 並將其加入到product
byid
: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