Supposons que j'ai une liste de valeurs, telle que 1, 2, 3, 4, 5
et une table dans laquelle certaines de ces valeurs existent dans une colonne. Voici un exemple:
id name
1 Alice
3 Cindy
5 Elmore
6 Felix
Je souhaite créer une instruction SELECT
qui inclura toutes les valeurs de ma liste ainsi que les informations des lignes correspondant à ces valeurs, c.-à-d., Effectue un LEFT OUTER JOIN
entre ma liste et la table.
id name
1 Alice
2 (null)
3 Cindy
4 (null)
5 Elmore
Comment faire cela sans créer une table temporaire ni utiliser plusieurs opérateurs UNION
?
Si vous utilisez Microsoft SQL Server 2008 ou une version ultérieure, vous pouvez utiliser Table Value Constructor
Select v.valueId, m.name
From (values (1), (2), (3), (4), (5)) v(valueId)
left Join otherTable m
on m.id = v.valueId
Je ne sais pas si Oracle a une construction similaire
la solution suivante pour Oracle est adoptée à partir de this source . L'idée de base est d'exploiter les requêtes hiérarchiques d'Oracle. vous devez spécifier une longueur maximale de la liste (100 dans l'exemple de requête ci-dessous).
select d.lstid
, t.name
from (
select substr(
csv
, instr(csv,',',1,lev) + 1
, instr(csv,',',1,lev+1 )-instr(csv,',',1,lev)-1
) lstid
from (select ','||'1,2,3,4,5'||',' csv from dual)
, (select level lev from dual connect by level <= 100)
where lev <= length(csv)-length(replace(csv,','))-1
) d
left join test t on ( d.lstid = t.id )
;
découvrez ce violon sql pour le voir fonctionner.
Un peu tard, mais pour Oracle, vous pourriez faire quelque chose comme ceci pour obtenir un tableau de valeurs:
SELECT rownum + 5 /*start*/ - 1 as myval
FROM dual
CONNECT BY LEVEL <= 100 /*end*/ - 5 /*start*/ + 1
... Et ensuite, joignez ça à votre table:
SELECT *
FROM
(SELECT rownum + 1 /*start*/ - 1 myval
FROM dual
CONNECT BY LEVEL <= 5 /*end*/ - 1 /*start*/ + 1) mypseudotable
left outer join myothertable
on mypseudotable.myval = myothertable.correspondingval
En supposant que myTable soit le nom de votre table, le code suivant devrait fonctionner.
;with x as
(
select top (select max(id) from [myTable]) number from [master]..spt_values
),
y as
(select row_number() over (order by x.number) as id
from x)
select y.id, t.name
from y left join myTable as t
on y.id = t.id;
Attention: Ceci est une implémentation de SQL Server.
Supposons que votre table ayant les valeurs 1,2,3,4,5
s'appelle list_of_values
et que la table contenant certaines valeurs, mais que la colonne de nom s'appelle some_values
, vous pouvez procéder comme suit:
SELECT B.id,A.name
FROM [list_of_values] AS B
LEFT JOIN [some_values] AS A
ON B.ID = A.ID
Pour obtenir les numéros séquentiels requis pour une partie de la sortie (cette méthode élimine les valeurs à saisir pour n nombres):
declare @site as int
set @site = 1
while @site<=200
begin
insert into ##table
values (@site)
set @site=@site+1
end
Résultat final [étape ci-dessus]:
select * from ##table
select v.id,m.name from ##table as v
left outer join [source_table] m
on m.id=v.id