将 PostgreSQL 函数包装在另一个函数中以有条件地组合结果
Wrap PostgreSQL functions in another to conditionally combine results
我有一个函数 get_oversight(int)
returns 单列:
person_id
----------
100
101
102
103
104
与另一个函数get_unfiltered_responsibility(int)
相同returns的结构:
person_id
----------
100
103
104
我需要第三个函数来评估 returns 以上的一个子集。这是一些伪代码:
def function get_responsibility(person_id int):
oversight = get_oversight(person_id)
unfiltered_responsibility = get_responsibility(person_id)
if number_of_records(unfiltered_responsibility) == 0:
return oversight
else
return intersection(unfiltered_responsibility, oversight)
# only ids from unfiltered_responsibility that are ALSO IN oversight
第三个功能会是什么样子? (使用 v9.6)
假设这两个函数永远不会 return 重复。否则,您必须准确定义如何处理这些问题。
在 plpgsql 函数中 你可以方便地使用特殊变量 FOUND
CREATE OR REPLACE FUNCTION get_combo_plpgsql(int)
RETURNS TABLE(person_id int) LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY
SELECT *
FROM get_oversight()
JOIN get_unfiltered_responsibility() USING (person_id);
IF NOT FOUND THEN
RETURN QUERY
SELECT * FROM get_oversight();
END IF;
END
$func$;
这 仅 假设 get_unfiltered_responsibility()
总是 return 是 get_oversight()
的子集,就像您的示例数据似乎暗示的那样。然后,如果连接 return 没有行,我们可以得出结论 get_unfiltered_responsibility()
是空的。
相关:
- Why is IS NOT NULL false when checking a row type?
或者,这个 CTE 包裹在一个简单的 SQL 函数中 在任何情况下都有效,无论是否是子集(也可以是 plpgsql 函数,如果需要):
CREATE OR REPLACE FUNCTION get_combo_sql(int)
RETURNS TABLE(person_id int) LANGUAGE sql AS
$func$
WITH cte AS (SELECT * FROM get_unfiltered_responsibility())
SELECT *
FROM get_oversight() o
WHERE EXISTS (
SELECT FROM cte
WHERE person_id = o.person_id
)
OR NOT EXISTS (TABLE cte)
$func$;
相关:
db<>fiddle here
我有一个函数 get_oversight(int)
returns 单列:
person_id
----------
100
101
102
103
104
与另一个函数get_unfiltered_responsibility(int)
相同returns的结构:
person_id
----------
100
103
104
我需要第三个函数来评估 returns 以上的一个子集。这是一些伪代码:
def function get_responsibility(person_id int):
oversight = get_oversight(person_id)
unfiltered_responsibility = get_responsibility(person_id)
if number_of_records(unfiltered_responsibility) == 0:
return oversight
else
return intersection(unfiltered_responsibility, oversight)
# only ids from unfiltered_responsibility that are ALSO IN oversight
第三个功能会是什么样子? (使用 v9.6)
假设这两个函数永远不会 return 重复。否则,您必须准确定义如何处理这些问题。
在 plpgsql 函数中 你可以方便地使用特殊变量 FOUND
CREATE OR REPLACE FUNCTION get_combo_plpgsql(int)
RETURNS TABLE(person_id int) LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY
SELECT *
FROM get_oversight()
JOIN get_unfiltered_responsibility() USING (person_id);
IF NOT FOUND THEN
RETURN QUERY
SELECT * FROM get_oversight();
END IF;
END
$func$;
这 仅 假设 get_unfiltered_responsibility()
总是 return 是 get_oversight()
的子集,就像您的示例数据似乎暗示的那样。然后,如果连接 return 没有行,我们可以得出结论 get_unfiltered_responsibility()
是空的。
相关:
- Why is IS NOT NULL false when checking a row type?
或者,这个 CTE 包裹在一个简单的 SQL 函数中 在任何情况下都有效,无论是否是子集(也可以是 plpgsql 函数,如果需要):
CREATE OR REPLACE FUNCTION get_combo_sql(int)
RETURNS TABLE(person_id int) LANGUAGE sql AS
$func$
WITH cte AS (SELECT * FROM get_unfiltered_responsibility())
SELECT *
FROM get_oversight() o
WHERE EXISTS (
SELECT FROM cte
WHERE person_id = o.person_id
)
OR NOT EXISTS (TABLE cte)
$func$;
相关:
db<>fiddle here