GROUP BY 使用 MIN() 聚合函数给出错误结果

den*_*nny 7 mysql aggregate group-by

我有一张看起来像这样的表:

+------+--------+--------------+------+--------+------ -+------+------------+
| 身份证 | 代码 | 类别 | 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;
Run Code Online (Sandbox Code Playgroud)

为什么组通过得到错误的结果?它正在返回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 |
+------+--------+--------------+------+--------+------ -+------+------------+

Rol*_*DBA 11

作为一名 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
Run Code Online (Sandbox Code Playgroud)

做好三件事

  1. 使查询成为子查询
  2. 使用price的别名,而不是上total
  3. 将其连接回产品表,code然后price

这是建议的查询

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

或者

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;
Run Code Online (Sandbox Code Playgroud)

为此检查SQL Fiddle

试一试 !!!

更新 2017-01-06 16:17 美国东部时间

如果给定代码存在超过 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);
Run Code Online (Sandbox Code Playgroud)

签出SQL Fiddle


joa*_*olo 5

这应该够了吧:

SELECT
    p.*
FROM
    product p
    JOIN
    (
        SELECT
            code, min(price) AS min_price
        FROM
            product
        GROUP BY
            code
    ) m ON p.code = m.code AND p.price = m.min_price 
ORDER BY
    p.id ;
Run Code Online (Sandbox Code Playgroud)

警告:如果有关系(即:min(price) 出现在每组超过一行中),将返回所有行。如果在平局的情况下,您想要另一种行为,事情会变得更加复杂……需要第二个选择标准(如果可能,一个不能获得另一个平局的标准),以及另一个级别的subquerying.

您也可以检查此查询@ SQLFiddle

您可以检查所有@RolandoMySQLDBA 对GROUP BYmySQL 中a 后面的所有“非标准”事物的解释。它很容易变得棘手。