Quando você
JOIN
duas ou mais tabelas juntas, você obtém efetivamente um produto cartesiano para essas tabelas para as quais um filtro declarado no JOIN
condição é aplicada. Isso é mais óbvio quando você usa um
JOIN
implícito obsoleto sintaxe. O
LEFT JOIN
garante que você não receba menos linhas do que a tabela mais à esquerda contém, i. e. cada linha da tabela mais à esquerda é retornada pelo menos uma vez. Você ainda pode obter mais linhas, se o filtro não for um mapeamento de linha um para um.
No seu caso:
SELECT (b.descr || ' - ' || c.descr) description
FROM tbl1 a
LEFT JOIN
tbl2 b
ON b.ACCOUNT = a.ACCOUNT
LEFT JOIN
tbl3 c
ON c.product = a.product
WHERE a.descr50 = ' '
ou
acccount
ou product
não são únicos em b
ou c
. Para estas linhas:
a.account
1
2
3
b.account b.description
1 Account 1
2 Account 2 - old
2 Account 2 - new
, o
JOIN
retornará o seguinte:a.account b.account b.description
1 1 Account 1
2 2 Account 2 - old
2 2 Account 2 - new
3 NULL NULL
, fornecendo mais linhas do que qualquer uma das tabelas contém.
Para escolher apenas a primeira descrição correspondente de qualquer tabela, use isto:
SELECT (
SELECT FIRST_VALUE(descr) OVER (ORDER BY descr)
FROM tbl2 b
WHERE b.account = a.account
AND rownum = 1
) || ' - ' ||
(
SELECT FIRST_VALUE(descr) OVER (ORDER BY descr)
FROM tbl3 c
WHERE c.product= a.product
AND rownum = 1
) description
FROM tbl1 a
WHERE a.descr50 = ' '
Para atualizar, basta envolver a consulta em uma visualização inline:
UPDATE (
SELECT (
SELECT FIRST_VALUE(descr) OVER (ORDER BY descr)
FROM tbl2 b
WHERE b.account = a.account
AND rownum = 1
) || ' - ' ||
(
SELECT FIRST_VALUE(descr) OVER (ORDER BY descr)
FROM tbl3 c
WHERE c.product= a.product
AND rownum = 1
) description
FROM tbl1 a
WHERE a.descr50 = ' '
)
SET descr50 = description