小编Jar*_*bzo的帖子

如何将 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
查看次数

验证 json[] 数组不为空的最快方法是什么?

我想验证一json[]the_array不为空。对于普通数组,我可以检查:

the_array != '{}'
Run Code Online (Sandbox Code Playgroud)

但是,这不适用于 a json[],如下所示:

select '{}'::json[] != '{}'
ERROR:  could not identify an equality operator for type json
Run Code Online (Sandbox Code Playgroud)

我可以改用以下检查:

array_length(the_array, 1) != null // yes, array_length on an
                                      empty array returns null
Run Code Online (Sandbox Code Playgroud)

我担心这array_length()会遍历整个数组以计算项目数,然后返回该计数。就我而言,我不需要数组的实际大小,我只需要知道它是否为空。

那么,是否array_length()遍历整个数组?如果是这样,是否有更好的方法来检查 json 数组是否为空?

postgresql array json

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

如何用 LEFT JOIN 替换 SELECT 子句中的多个相关子查询?

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

我有简单的表格布局:

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

以下查询选择嵌入了人员的所有类:

select    class.identifier, array(select person.identifier from person where person.class_identifier = class.identifier) as persons
from      class
order by  class.identifier;
Run Code Online (Sandbox Code Playgroud)

在试验和学习更多有关相关子查询的信息时,我注意到可以通过用 aLEFT JOIN组合替换相关子查询来重写上面的查询GROUP BY

select     class.identifier, array_agg(person.identifier) as persons
from       class
left join  (
             select  person.identifier, person.class_identifier
             from    person
           ) as person
on         class.identifier = person.class_identifier
group by   class.identifier
order by   class.identifier;
Run Code Online (Sandbox Code Playgroud)

请注意,我假设每个班级至少有一个人。如果没有,我可以添加coalesce()周围json_agg

在我的第二种情况下,我将选择所有嵌入人员房间的类。让我们首先以与上面第一个查询相同的方式编写:

select    class.identifier, array(select …
Run Code Online (Sandbox Code Playgroud)

postgresql

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

标签 统计

postgresql ×3

aggregate ×1

array ×1

json ×1

order-by ×1

subquery ×1