如何编写PL/SQL函数统计单条记录的distinct Presta值数量
Oracle函数实现:统计FORM表中拼接后presta值的distinct数量
我帮你写了一个适用于Oracle数据库的函数,完美匹配你描述的需求——根据主键ID_FORM拼接ACT_n、DESC_n、ECH_n为presta_n,然后统计去重后的非空presta值数量(支持最多8组字段)。
函数代码
CREATE OR REPLACE FUNCTION COUNT_DISTINCT_PRESTA(p_id_form INT) RETURN INT IS v_distinct_count INT; BEGIN -- 将8组字段拼接结果行转列,再统计去重的非空值数量 SELECT COUNT(DISTINCT t.presta) INTO v_distinct_count FROM ( SELECT ACT_1 || DESC_1 || ECH_1 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_2 || DESC_2 || ECH_2 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_3 || DESC_3 || ECH_3 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_4 || DESC_4 || ECH_4 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_5 || DESC_5 || ECH_5 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_6 || DESC_6 || ECH_6 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_7 || DESC_7 || ECH_7 AS presta FROM FORM WHERE ID_FORM = p_id_form UNION ALL SELECT ACT_8 || DESC_8 || ECH_8 AS presta FROM FORM WHERE ID_FORM = p_id_form ) t WHERE t.presta IS NOT NULL; RETURN v_distinct_count; END; /
函数说明
- 行转列处理:用
UNION ALL把每个presta_n转换成单独的行,这样可以统一进行去重和统计操作。 - NULL值处理:Oracle中只要拼接的字段有一个为
NULL,整个拼接结果就会是NULL,我们通过WHERE t.presta IS NOT NULL过滤掉这些无效值。 - 去重统计:
COUNT(DISTINCT t.presta)会自动计算所有非空presta值的唯一数量,完全符合你的需求。
测试验证
针对你给出的测试数据,调用函数的结果如下:
- 对于
ID_FORM=1:执行SELECT COUNT_DISTINCT_PRESTA(1) FROM DUAL;返回3(对应A1D12、A2D212、A3D36三个唯一值) - 对于
ID_FORM=2:执行SELECT COUNT_DISTINCT_PRESTA(2) FROM DUAL;返回3(对应A1D12、A1D22、A3D12三个唯一值) - 对于
ID_FORM=3:执行SELECT COUNT_DISTINCT_PRESTA(3) FROM DUAL;返回2(对应A3D42、A1D112两个唯一值)
适配调整
如果你的实际表中n的上限不是8(比如只有4组字段),直接删掉多余的UNION ALL行即可,函数逻辑不受影响。
内容的提问来源于stack exchange,提问作者Romain
相关产品推荐
相关产品推荐

