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