You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需枚举列即可按子表所有列分组?Postgres方案咨询

无需枚举所有列实现GROUP BY的方法

标准SQL情况

标准SQL并没有提供类似COLUMNS(t1)这种直接引用整张表所有列的语法,必须显式列出所有需要作为分组键的列。虽然部分数据库厂商有自己的扩展语法,但不属于SQL标准范畴。

PostgreSQL解决方案

在PostgreSQL中有两种实用的方法可以避免枚举所有列:

方法1:直接使用表别名加*

PostgreSQL支持在GROUP BY子句中使用t1.*来代表表t1的所有列,同时在SELECT子句中也可以用t1.*来获取这些列,只要非聚合列与分组键完全对应即可。

针对你的需求,查询可以改写为:

SELECT t1.*, t2.col_k, COUNT(*)
FROM t1
JOIN t2 ON t2.col1 = t1.col1
WHERE t2.col1 > 0
GROUP BY t1.*, t2.col_k;

这个写法会自动将t1的所有列作为分组条件,同时返回这些列的值,完全省去了枚举列名的繁琐。

方法2:动态生成SQL语句

如果需要更灵活的场景(比如需要动态适配表结构变化),可以利用PostgreSQL的系统表和动态SQL功能生成查询语句。

方式A:手动生成列名(psql环境)

在psql命令行中,先执行以下语句获取t1的所有列名:

SELECT string_agg(quote_ident(column_name), ', ') 
FROM information_schema.columns 
WHERE table_name = 't1' AND table_schema = 'public'; -- 替换为你的表所属schema

将返回的列名字符串复制到原查询的SELECT和GROUP BY子句中即可。

方式B:用PL/pgSQL函数自动执行

创建一个函数来动态生成并执行查询,无需手动复制列名:

CREATE OR REPLACE FUNCTION get_grouped_data() 
RETURNS TABLE (t1_row t1, col_k t2.col_k%TYPE, count bigint) AS $$
DECLARE
    t1_columns text;
BEGIN
    SELECT string_agg(quote_ident(column_name), ', ') 
    INTO t1_columns
    FROM information_schema.columns
    WHERE table_name = 't1' AND table_schema = 'public';

    RETURN QUERY EXECUTE format(
        'SELECT t1.*, t2.col_k, COUNT(*)
         FROM t1
         JOIN t2 ON t2.col1 = t1.col1
         WHERE t2.col1 > 0
         GROUP BY t1.*, t2.col_k'
    );
END;
$$ LANGUAGE plpgsql;

调用该函数即可获取结果:

SELECT * FROM get_grouped_data();

内容的提问来源于stack exchange,提问作者Owen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:38:31