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 BY
为cowboy 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)
做好三件事
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);
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)
如果给定代码存在超过 1 行具有相同的最低价格,则您必须进行查询,将其设为子查询,加入它以检索每个 ( code
, price
)的最小 id并将其连接回product
by 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)
这应该够了吧:
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 BY
mySQL 中a 后面的所有“非标准”事物的解释。它很容易变得棘手。
归档时间: |
|
查看次数: |
14273 次 |
最近记录: |