繁体   English   中英

在postgresql中通过max(col)获取行过滤

[英]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;

@戈登的回答几乎是不正确的。 如果列可以为NULLmax(bz)ORDER BY bz DESC之间存在细微差别。 经常被忽视并引起很多头痛。

这可能会咬你, 即使列bz定义为NOT NULL 外连接可以为列引入NULL值。 在这个简单的查询中不会有效,但可以在更复杂的查询中。

虽然minmaxcount等聚合函数忽略 NULL值,但在ORDER BY子句中使用相同的列时必须以某种方式处理这些值。
在默认排序顺序中, NULL值排序最后 当排序顺序变了, DESCNULL排序第一个值。 一定要保持一致。
因此,如果任何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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM