Lorsque vous JOIN deux ou plusieurs tables ensemble, vous obtenez effectivement un produit cartésien pour ces tables auquel un filtre indiqué dans le JOIN condition est appliquée.
Ceci est plus évident lorsque vous utilisez un JOIN implicite obsolète syntaxe.
Le LEFT JOIN garantit que vous n'obtenez pas moins rangées que le tableau le plus à gauche contient, c'est-à-dire. e. chaque ligne du tableau le plus à gauche est renvoyée au moins une fois.
Vous pouvez toujours obtenir plus de lignes, si le filtre n'est pas un mappage de lignes un à un.
Dans votre cas :
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 = ' '
soit acccount ou product ne sont pas uniques dans b ou c .
Pour ces lignes :
a.account
1
2
3
b.account b.description
1 Account 1
2 Account 2 - old
2 Account 2 - new
, le JOIN renverra ce qui suit :
a.account b.account b.description
1 1 Account 1
2 2 Account 2 - old
2 2 Account 2 - new
3 NULL NULL
, vous donnant plus de lignes que n'en contient l'une ou l'autre des tables.
Pour choisir simplement la première description correspondante dans l'un ou l'autre des tableaux, utilisez ceci :
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 = ' '
Pour mettre à jour, encapsulez simplement la requête dans une vue intégrée :
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