我正在尝试创建一个聚合函数,它接受一组记录,进行一些计算并返回一个数字。
我已经得到了以下虚拟示例:
CREATE OR REPLACE FUNCTION dummy_func(text) RETURNS int
AS
$$
DECLARE
rec record;
num int := 0;
BEGIN
FOR rec IN EXECUTE $1
LOOP
IF POSITION('some text' IN rec.known_column_name) = 1
THEN
num := num + 1;
END IF;
END LOOP;
RETURN num;
END;
$$ LANGUAGE PLPGSQL;
如果我输入
SELECT dummy_func('select * from some_table');
,它按预期工作。
但是,我想这样做,以便我可以使用多种功能和条件,例如:
SELECT conditional_col_1, dummy_func_1(*), dummy_func_2(*)
FROM some_table
WHERE conditional_col_2 = 'some val'
GROUP BY 1
如何将我的虚拟示例重写为能够如此运行(或使用一堆UNIONS ALL等)?
回应Hambone
如果我有以下逻辑(计算'a'或计算'b'*列的东西3)
CREATE OR REPLACE FUNCTION count_a(text) RETURNS int
AS
$$
DECLARE
rec record;
num int := 0;
BEGIN
FOR rec IN EXECUTE $1
LOOP
num := num + length(regexp_replace(rec.something1, '[^a]+', '', 'g'));
END LOOP;
RETURN num;
END;
$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION count_e_times_something3(text) RETURNS int
AS
$$
DECLARE
rec record;
num int := 0;
BEGIN
FOR rec IN EXECUTE $1
LOOP
num := num + length(regexp_replace(rec.something1, '[^e]+', '', 'g')) * rec.something3::int;
END LOOP;
RETURN num;
END;
$$ LANGUAGE PLPGSQL;
我目前必须单独执行它们,
$=# SELECT count_a('SELECT * FROM MY_TEST WHERE something2 = ''A'' and something1 = ''0''');
-[ RECORD 1 ]
count_a | 0
$=# SELECT count_a('SELECT * FROM MY_TEST WHERE something2 = ''A'' and something3 = ''0''');
-[ RECORD 1 ]
count_a | 2
$=# SELECT count_e_times_something3('SELECT * FROM MY_TEST WHERE something2 = ''A'' and something3 = ''0''');
-[ RECORD 1 ]------------+--
count_e_times_something3 | 0
$=# SELECT count_e_times_something3('SELECT * FROM MY_TEST WHERE something2 = ''A'' and something3 = ''1''');
-[ RECORD 1 ]------------+--
count_e_times_something3 | 7
如果我可以使用以下查询会更好(我知道我需要定义一个聚合函数,但我找不到任何返回标量的记录):
SELECT something2, count_a(*), count_e_times_something3(*) FROM MY_TEST WHERE something3 = '1';
something: 'A'
count_a: 3
count_e_times_something3: 7
something: 'B'
count_a: 3
count_e_times_something3: 2
count_a导致3是巧合