Как объединить оператор CASE с LATERAL JOIN в PostgreSQL?

Мне нужно вызывать функцию несколько раз для каждой строки выбора, потому что функция имеет несколько параметров OUT, все из которых мне нужны

Например

SELECT
   a, b,
   (SELECT out1 from func(a)),
   (SELECT out2 from func(a))
FROM 
   table1

Чтобы вызвать эту функцию только один раз, я использую боковое соединение

SELECT 
   a, b,
   lat.out1,
   lat.out2
LEFT OUTER JOIN LATERAL (
   SELECT out1, out2 FROM func(a)
) lat ON (TRUE)

Проблема в том случае a обнуляемый func выдает исключение при вызове с нулем. Тогда без объединений я бы сделал это так

SELECT
   a, b,
   CASE WHEN a IS NOT NULL 
       THEN out1 from func(a)
   END,
   CASE WHEN a IS NOT NULL 
       THEN out2 from func(a)
   END
FROM 
   table1

Но как я мог реализовать это, используя lateral joins? Есть ли способ использовать CASE внутри бокового соединения? Или есть другой способ вызвать процедуру только один раз?

1 ответ

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

create or replace function wrap_func(a int)
returns table(out1 int, out2 int)
as $$
begin
    if a is null then
        return;
    end if;
    return query (
        select  out1, out2
        from    func(a)
    );
end;
$$ language plpgsql;

Если вы называете обертку в вашем lateral присоединяйтесь, он будет вести себя так, как вы ожидаете.

Другие вопросы по тегам