Tenho uma função cara e ela só fornece dados relevantes quando certas condições são atendidas. Esses dados são inseridos no resultado através de LEFT JOIN LATERAL conforme mostrado abaixo. Da forma como funciona agora, a função é chamada para cada linha.
Existe uma maneira de reescrevê-lo para que seja chamado apenas para linhas onde t1.type é igual a 5? O exemplo abaixo ainda chama a função para cada linha, embora eu tenha uma condição definida.
SELECT t1.name, t1.type, t2.col1, t2.col2
FROM table1 t1
LEFT JOIN LATERAL function_name(t1.col1, t1.col2) AS t2 ON t1.type = 5;
Caso de teste:
CREATE TABLE table1 (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
type INTEGER,
col1 INTEGER,
col2 INTEGER
);
-- Sample data for table1
INSERT INTO table1 (name, type, col1, col2)
VALUES
('Row 1', 5, 10, 20),
('Row 2', 7, 15, 25),
('Row 3', 10, 30, 40);
CREATE OR REPLACE FUNCTION function_name(col1_arg INTEGER, col2_arg INTEGER)
RETURNS TABLE (col1 INTEGER, col2 INTEGER)
AS $$
BEGIN
RAISE LOG 'Function called';
RETURN QUERY SELECT col1_arg * 2 AS col1, col2_arg * 3 AS col2;
END;
$$ LANGUAGE plpgsql;
-- Test Query
SELECT t1.name, t1.type, t2.col1, t2.col2
FROM table1 t1
LEFT JOIN LATERAL function_name(t1.col1, t1.col2) AS t2 ON t1.type = 5;
violino
Teste algo semelhante a:
Tentativa nº 1: colocar sua condição na cláusula WHERE funciona, mas altera os resultados da consulta, pois removerá todas as linhas com type!=5:
... no entanto, você pode colocar as linhas novamente:
Se "tabela1" não for uma tabela, mas uma consulta complicada, você poderá colocá-la em um CTE materializado para evitar fazer isso duas vezes.
Tentativa nº 2: adicione "RETURNS NULL ON NULL INPUT" à função e chame-a com nulos quando você realmente não quiser chamá-la, o que não executará a função, o que é muito mais rápido:
(você também pode usar CASE para definir todos os parâmetros da função como NULL quando não quiser chamá-la).
Tentativa nº 3
Isso parece funcionar bem, a função só é chamada quando deveria.
Tentativa nº 4:
Isso também funciona bem.