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

PostgreSQL中如何使用表列值作为函数参数生成汇总统计结果

问题说明

我在PostgreSQL中通过如下SQL创建了summaryTable表:

CREATE TABLE summaryTable AS (
    SELECT d.name, d.store_id, d.rental_id
    FROM detailedTable AS d
    GROUP BY d.store_id, d.name
    ORDER BY d.name ASC
) 

我之前写了一个入参为电影类型、返回该类型出现次数的自定义函数,想把函数计算结果作为新列加入summaryTable,入参取表中 d.name 字段的值。
需要实现的逻辑:逐行取首列的类型名称作为函数入参,统计对应类型的出现次数,最终返回包含「类型名称、1号门店该类型出现次数、2号门店该类型出现次数」的结果表。

当前已写的函数仅支持统计1号门店的数值,无法满足需求,代码如下:

CREATE OR REPLACE FUNCTION countGenre (genre varchar)
RETURNS integer AS $totals$
DECLARE totals integer;
BEGIN
    SELECT COUNT(d.name) INTO totals
    FROM detailedTable AS d
    WHERE d.name = genre AND d.store_id = 1
    GROUP BY d.name;
    RETURN totals;
    END; $totals$
LANGUAGE plpgsql;
实现方案

推荐方案:直接条件聚合(性能最优)

不需要自定义函数逐行调用,直接通过条件聚合一次查询就能得到目标结果,数据量较大时性能远高于逐行函数调用:

SELECT
    name AS genre_name,
    COUNT(*) FILTER (WHERE store_id = 1) AS store1_count,
    COUNT(*) FILTER (WHERE store_id = 2) AS store2_count
FROM detailedTable
GROUP BY name
ORDER BY name ASC;

PostgreSQL原生支持FILTER子句做条件计数,比CASE WHEN写法更简洁易读。

方案2:改造自定义函数适配需求

如果必须使用自定义函数实现,可以把函数改造为返回两个门店计数的出参,避免多次扫表:

CREATE OR REPLACE FUNCTION countGenre (
    IN genre varchar,
    OUT store1_total integer,
    OUT store2_total integer
) AS $$
BEGIN
    SELECT
        COUNT(*) FILTER (WHERE store_id = 1),
        COUNT(*) FILTER (WHERE store_id = 2)
    INTO store1_total, store2_total
    FROM detailedTable
    WHERE name = genre;
END;
$$ LANGUAGE plpgsql;

调用函数生成目标结果的SQL如下:

SELECT DISTINCT
    name AS genre_name,
    (countGenre(name)).store1_total AS store1_count,
    (countGenre(name)).store2_total AS store2_count
FROM summaryTable
ORDER BY name ASC;

注意:如果后续门店数量扩展,不建议继续用函数加固定出参的写法,直接用条件聚合的扩展性更好。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:15:41