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

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

E.g.

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 имеет значение NULL. 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 внутри бокового соединения? Или есть другой способ вызвать процедуру только один раз?


person Juri Krainjukov    schedule 16.03.2015    source источник
comment
Я бы изменил функцию, чтобы она могла обрабатывать значение null   -  person a_horse_with_no_name    schedule 16.03.2015


Ответы (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, она будет вести себя так, как вы ожидаете.

person Andomar    schedule 16.03.2015