有没有办法在单个 psql 查询中返回总计数和行数?

Posted

技术标签:

【中文标题】有没有办法在单个 psql 查询中返回总计数和行数?【英文标题】:Is there a way to return a total count and rows in a single psql query? 【发布时间】:2022-01-21 04:16:59 【问题描述】:

考虑以下几点:

CREATE TABLE IF NOT EXISTS person (
    id                  BIGSERIAL,
    favorite_color      TEXT,
    PRIMARY KEY (id)
);


INSERT INTO person (favorite_color) VALUES ('red');
INSERT INTO person (favorite_color) VALUES ('green');
INSERT INTO person (favorite_color) VALUES ('blue');
INSERT INTO person (favorite_color) VALUES ('blue');
INSERT INTO person (favorite_color) VALUES ('blue');

我现在想查询表,为favorite_color = blue 并返回所有行的所有行提供COUNT。如何使用单个 postgresql 查询实现以下输出?


    "total" 3,
    "results": [
        "id": 3, "favorite_color": "blue",
        "id": 4, "favorite_color": "blue",
        "id": 5, "favorite_color": "blue",
    ]

我知道怎么写SQL语句,我问是否可以写一个SQL语句来达到我想要的结果,反对两次访问数据库(一次用于计数,第二次用于结果)。

【问题讨论】:

所以不是“反对两次打击数据库”,而是只打击一次,但更难? ?????? 【参考方案1】:

您可以使用count() 的窗口版本来获取计数。

SELECT json_build_object('total', max(total),
                         'results', json_agg(element))
       FROM (SELECT count(*) OVER () AS total,
                    row_to_json(person) AS element
                    FROM person
                    WHERE favorite_color = 'blue') AS x;

db<>fiddle

【讨论】:

这里为什么需要使用max() @KeSi-Kung:因为json_agg() 的聚合暗示。由于total 对每一行都是相同的,因此也可以使用min() 或其他可能的聚合函数。【参考方案2】:

这是一个带有标量子查询且没有窗口函数或min() 的替代方案。让优化器独自完成它的工作。

with p as (select * from person where favorite_color = 'blue')
select jsonb_build_object(
 'total', count(*), 
 'results',  
 (
  select jsonb_agg(to_jsonb(t)) 
    from (select id, favorite_color from p) t
 ))
from p;

【讨论】:

这似乎是返回表中所有行的计数,而不是与查询匹配的行。 @KeSi-Kung 哦,当然。答案已更新。

以上是关于有没有办法在单个 psql 查询中返回总计数和行数?的主要内容,如果未能解决你的问题,请参考以下文章

Java获得数据库查询结果的列数和行数,打印查询结果

栅格数据的列数和行数很大怎么回事

查询所有HIVE表分区数据量

查询所有HIVE表分区数据量

查询所有HIVE表分区数据量

在单个 oracle 查询中获取行数和其他列值