MySQL 是唯一允许通过处理损坏(MySQL 术语中的“丢失”)组的 DBMS。所有其他 DBMS(包括 Postgres)都会拒绝您的原始声明。
在 Postgres 中,您可以使用distinct on
运算符来实现相同的目的:
select distinct on (origin)
origin,
destiny,
distance
from places
order by origin, distance;
ANSI 解决方案是这样的:
select p.origin,
p.destiny,
p.distance
from places p
join (select p2.origin, min(p2.distance) as distance
from places p2
group by origin
) t on t.origin = p.origin and t.distance = p.distance
order by origin;
或者不使用窗口函数连接
select t.origin,
t.destiny,
t.distance
from (
select origin,
destiny,
distance,
min(distance) over (partition by origin) as min_dist
from places
) t
where distance = min_dist
order by origin;
或另一种具有窗口功能的解决方案:
select distinct origin,
first_value(destiny) over (partition by origin order by distance) as destiny,
min(distance) over (partition by origin) as distance
from places
order by origin;
我的猜测是第一个(特定于 Postgres)可能是最快的。
这是所有三个解决方案的 SQLFiddle:http ://sqlfiddle.com/#!12/68308/2
请注意,MySQL 结果实际上可能不正确,因为它将返回一个任意(=随机)的值作为命运。MySQL 返回的值可能不是属于最低距离的值。
可以在此处找到有关通过在 MySQL 中处理的损坏组的更多详细信息:http ://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/