[英]Get row filtering by max(col) in postgresql
我正在使用postgresql,我对它不熟悉。 这段代码有效,但我想知道我是否可以用更简单的方式编写它。 在这里,我加入了bar,在子查询中加入吧。 我希望有一些简单的东西,比如select * from bar group by baz using max(z)
select *
from foo f
join bar b on(f.baz=b.baz AND b.z in (select max(z) from bar group by baz))
where uid1 = 120
只需使用distinct on
:
select distinct on (f.baz) *
from foo f join
bar b
on f.baz = b.baz
where uid1 = 120
order by f.baz, b.z desc;
@戈登的回答几乎是不正确的。 如果列可以为NULL
则max(bz)
和ORDER BY bz DESC
之间存在细微差别。 经常被忽视并引起很多头痛。
这可能会咬你, 即使列bz
定义为NOT NULL
。 外连接可以为列引入NULL
值。 在这个简单的查询中不会有效,但可以在更复杂的查询中。
虽然min
, max
或count
等聚合函数忽略 NULL
值,但在ORDER BY
子句中使用相同的列时,必须以某种方式处理这些值。
在默认排序顺序中, NULL
值排序最后 。 当排序顺序变了, DESC
, NULL
排序第一个值。 一定要保持一致。
因此,如果任何NULL
值在对等体集中,则从DISTINCT ON
获取一行baz IS NULL
,其中您将从max(bz)
获得最大的非空值(如果有max(bz)
。 很可能不是你想要的。 您可以使用NULLS LAST
修复它:
另外,在使用SELECT *
,您不希望两次返回连接列baz
- 保证相同。 USING
子句派上用场,它只返回一次列。
所以:
SELECT DISTINCT ON (baz) *
FROM foo f
JOIN bar b USING (baz)
WHERE uid1 = 120 -- where from?
ORDER BY baz, b.z DESC NULLS LAST;
即使没有NULL
值, NULLS LAST
也不会受到伤害 - 除非你真的想要以NULL
值为准。
DISTINCT ON
详细说明:
由于uid1
来自baz
( 如注释 ),因此对于大表,此查询通常更快:
SELECT *
FROM foo f
JOIN (
SELECT DISTINCT ON (baz) *
FROM bar
WHERE uid1 = 120
ORDER BY baz, z DESC NULLS LAST
) b USING (baz);
根据表定义和数据分布,可能会有更快的查询技术:
嗨,
你可以在下面查询,
SELECT * FROM foo f
INNER JOIN (SELECT baz, MAX(z) FROM bar GROUP BY baz) b
ON (f.baz = b.baz)
WHERE f.uid1 = 120;
只需使用MAX(z)连接条形并填充所需的值。 uid1必须来自foo表,因为f用作别名,如果没有更改为b.uid1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.