I have a function get_oversight(int)
that returns a single column:
person_id
----------
100
101
102
103
104
And another function get_unfiltered_responsibility(int)
that returns the same structure:
person_id
----------
100
103
104
I need a 3rd function that evaluates and returns a subset of the above. Here's some pseudo code:
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
What would that 3rd function look like? (using v9.6)
Assuming that both functions never return duplicates. Else you'll have to define exactly how to deal with those.
In a PL/pgSQL function you can conveniently use the special variable 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($1)
JOIN get_unfiltered_responsibility($1) USING (person_id);
IF NOT FOUND THEN -- !
RETURN QUERY
SELECT * FROM get_oversight($1);
END IF;
END
$func$;
This only works on the assumption that get_unfiltered_responsibility()
always returns a subset of get_oversight()
, like your sample data seems to suggest. Then, if the join returns no rows, we can conclude that get_unfiltered_responsibility()
came up empty.
Related:
Alternatively, this CTE wrapped in a simple SQL function works in any case, subset or not (can be a PL/pgSQL function too, if needed):
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($1))
SELECT *
FROM get_oversight($1) o
WHERE EXISTS (
SELECT FROM cte
WHERE person_id = o.person_id
)
OR NOT EXISTS (TABLE cte)
$func$;
Related: