jph*_*jph 7 postgresql performance subquery postgresql-9.3 query-performance
假设我有两个表:
福:
id
baz
Run Code Online (Sandbox Code Playgroud)
酒吧:
id
foo_id
boom
Run Code Online (Sandbox Code Playgroud)
所以一个 Foo 有很多 Bars。我经常发现自己需要为给定的一组 Foo 计算跨条的聚合,但我也想要一些来自 Foo 的属性。这样做的两种最直接的方法是丑陋的:
方法#1:不必要的聚合函数
select
foo.id,
min(foo.baz) as baz,
min(bar.boom) as min_boom
from
foo
join
bar on foo.id = bar.foo_id
group by
foo.id;
Run Code Online (Sandbox Code Playgroud)
方法#2:不必要的按列分组
select
foo.id,
foo.baz,
min(bar.boom) as min_boom
from
foo
join
bar on foo.id = bar.foo_id
group by
foo.id,
foo.baz;
Run Code Online (Sandbox Code Playgroud)
当 Foo 除了“id”之外只有一个额外的列时,这并不是那么糟糕,但是如果需要包含许多列,那么分组的效率就会大大降低。像这样的查询解决了这两个问题,但似乎很笨拙:
select
foo.id,
foo.baz,
x.min_boom
from
foo
join
(select
foo_id,
min(boom) as min_boom
from
bar
group by
foo_id) x on x.foo_id = foo.id;
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?如果重要的话,平台是 Postgres。
And*_*y M 11
如果ID被定义作为主键,你可以省略所有分组富,你只要想为输出作为你被分组列ID。这种分组的特殊情况符合当前的 SQL 标准,并且在PostgreSQL 手册 中也有介绍,从 9.1 版本开始:
当存在 GROUP BY 或存在任何聚合函数时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数内或当未分组的列在功能上依赖于分组的列时,否则会有更多为未分组的列返回一个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在函数依赖性。
(加了重点。)
因此,如果foo.id是 PK,则此查询将有效:
select
foo.id,
foo.baz,
foo.whatever,
min(bar.boom) as min_boom
from
foo
join
bar on foo.id = bar.foo_id
group by
foo.id;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6749 次 |
最近记录: |