相关疑难解决方法(0)

为什么 array_agg() 比非聚合 ARRAY() 构造函数慢?

我刚刚查看了一些为8.4 之前的 PostgreSQL编写的旧代码,我看到了一些非常棒的东西。我记得以前有一个自定义函数可以做一些这样的事情,但我忘记了预先的array_agg()样子。回顾一下,现代聚合是这样写的。

SELECT array_agg(x ORDER BY x DESC) FROM foobar;
Run Code Online (Sandbox Code Playgroud)

然而,曾几何时,它是这样写的,

SELECT ARRAY(SELECT x FROM foobar ORDER BY x DESC);
Run Code Online (Sandbox Code Playgroud)

所以,我用一些测试数据试了一下..

CREATE TEMP TABLE foobar AS
SELECT * FROM generate_series(1,1e7)
  AS t(x);
Run Code Online (Sandbox Code Playgroud)

结果令人惊讶..#OldSchoolCool 方式要快得多:加速了 25%。此外,在没有ORDER 的情况下简化它,表现出同样的缓慢。

# EXPLAIN ANALYZE SELECT ARRAY(SELECT x FROM foobar);
                                                         QUERY PLAN                                                          
-----------------------------------------------------------------------------------------------------------------------------
 Result  (cost=104425.28..104425.29 rows=1 width=0) (actual time=1665.948..1665.949 rows=1 loops=1)
   InitPlan 1 (returns $0)
     ->  Seq Scan on foobar  (cost=0.00..104425.28 rows=6017728 width=32) (actual time=0.032..716.793 rows=10000000 loops=1) …
Run Code Online (Sandbox Code Playgroud)

postgresql benchmark aggregate array

16
推荐指数
2
解决办法
1万
查看次数

如何将 ORDER BY 和 LIMIT 与聚合函数结合使用?

我的问题的小提琴可以在https://dbfiddle.uk/?rdbms=postgres_10&fiddle=3cd9335fa07565960c1837aa65143685上找到。

我有一个简单的表格布局:

class
person: belongs to a class
Run Code Online (Sandbox Code Playgroud)

我想选择所有班级,对于每个班级,我想要按降序排列的所属人员的前两个人员标识符。

我通过以下查询解决了这个问题:

select     c.identifier, array_agg(p.identifier order by p.name desc) as persons
from       class as c
left join lateral (
             select   p.identifier, p.name
             from     person as p
             where    p.class_identifier = c.identifier
             order by p.name desc
             limit    2
           ) as p
on         true
group by   c.identifier
order by   c.identifier
Run Code Online (Sandbox Code Playgroud)

注意:我可以在SELECT子句中使用相关子查询,但作为学习过程的一部分,我试图避免这种情况。

如您所见,我order by p.name desc在两个地方申请:

  • 在子查询中
  • 在聚合函数中

有没有办法避免这种情况?我的坚持:

  • 首先,显然我不能删除order by子查询中的 ,因为这会给出一个不符合我上述要求的查询。

  • 其次,我认为order by聚合函数中的 不能被遗漏,因为子查询的行顺序不一定保留在聚合函数中?

我应该重写查询吗?

postgresql aggregate order-by subquery

9
推荐指数
1
解决办法
5936
查看次数

了解多表连接与聚合

我有一个关于如何JOIN在多个表上工作的基本问题。我想计算link1&中外键的出现次数link2

CREATE TABLE main (
   id SERIAL PRIMARY KEY,
   name text NOT NULL
);

CREATE TABLE link1 (
   id SERIAL PRIMARY KEY,
   main_id integer NOT NULL,
   CONSTRAINT main_id_fk FOREIGN KEY (main_id) REFERENCES main (id)
);

-- link2 is similar to link1
Run Code Online (Sandbox Code Playgroud)

SQL小提琴

当两列中的计数都不为零时,为什么下面的查询会给出计数的乘积(而不是总和)。

SELECT main.id, COUNT(link1.main_id) + COUNT(link2.main_id)
FROM main
LEFT JOIN link1 ON main.id=link1.main_id
LEFT JOIN link2 ON main.id=link2.main_id
GROUP BY main.id
Run Code Online (Sandbox Code Playgroud)

postgresql join aggregate

5
推荐指数
2
解决办法
1万
查看次数

标签 统计

aggregate ×3

postgresql ×3

array ×1

benchmark ×1

join ×1

order-by ×1

subquery ×1