Оберните функции PostgreSQL в другую для условного объединения результатов - PullRequest
1 голос
/ 23 сентября 2019

У меня есть функция get_oversight(int), которая возвращает один столбец:

person_id
----------
100
101
102
103
104

И еще одна функция get_unfiltered_responsibility(int), которая возвращает ту же структуру:

person_id
----------
100
103
104

Мне нужен третийфункция, которая оценивает и возвращает подмножество вышеперечисленного.Вот некоторый псевдокод:

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)

1 Ответ

0 голосов
/ 27 сентября 2019

Предполагая, что обе функции никогда не возвращают дубликаты.Иначе вам придется точно определить, как с ними обращаться.

В функции 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($1)
   JOIN   get_unfiltered_responsibility($1) USING (person_id);

   IF NOT FOUND THEN
      RETURN QUERY
      SELECT * FROM get_oversight($1);
   END IF;
END
$func$;

Этот только работает в предположении, что get_unfiltered_responsibility() всегда возвращает подмножество get_oversight(), как, по-видимому, и предполагают ваши данные выборки.Затем, если объединение не возвращает строк, мы можем заключить, что get_unfiltered_responsibility() оказалось пустым.

Related:

В качестве альтернативы этот 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($1))
SELECT *
FROM   get_oversight($1) o
WHERE  EXISTS (
   SELECT FROM cte
   WHERE  person_id = o.person_id
   )
OR NOT EXISTS (TABLE cte)
$func$;

Связано:

дБ <> скрипка здесь

...