2014-04-29 19 views
10

Supponiamo di avere un elenco di valori, ad esempio 1, 2, 3, 4, 5 e una tabella in cui alcuni di questi valori sono presenti nella stessa colonna. Ecco un esempio:Unione di un elenco di valori con righe di tabella in SQL

id name 
1 Alice 
3 Cindy 
5 Elmore 
6 Felix 

Voglio creare una dichiarazione SELECT che includerà tutti i valori dalla mia lista, così come le informazioni da quelle righe che corrispondono ai valori, cioè, effettuare una LEFT OUTER JOIN tra la mia lista e il tavolo, quindi il risultato sarebbe come segue:

id name 
1 Alice 
2 (null) 
3 Cindy 
4 (null) 
5 Elmore 

Come faccio a farlo senza creare una tabella temporanea o utilizzando più UNION operatori?

+0

Quale prodotto di database? –

+0

MS SQL Server o Oracle. – uncoder

risposta

18

Se in Microsoft SQL Server 2008 o versioni successive, è possibile utilizzare 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 

Non so se Oracle ha struttura simile

+0

Grazie; funziona in MS SQL. – uncoder

+0

funziona in postgresql 9.5.2 – jackpipe

+0

Questo è estremamente utile in una vasta gamma di circostanze –

1

Supponendo myTable è il nome della tabella, seguente codice dovrebbe lavoro.

;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; 

Attenzione: questo è l'attuazione di SQL Server.

fiddle

+0

Non sono sicuro di aver capito. Come e dove entra in gioco l'elenco dei valori (1, 2, 3, 4, 5)? – uncoder

+0

Beh, questo può gestire qualsiasi cosa, da 1 a qualunque sia il tuo id più alto (1,2,3,4,5, ...., n). –

+0

Ci scusiamo per ingannarti. Ho introdotto la colonna 'id' solo a scopo illustrativo. L'elenco di valori non deve rappresentare un elenco di ID, rownums o numeri sequenziali. Può essere costituito da stringhe arbitrarie o altri valori distinti. – uncoder

3

la seguente soluzione per Oracle è adottato da this source. l'idea di base è sfruttare le query gerarchiche di oracle. devi specificare una lunghezza massima della lista (100 nella query di esempio sotto).

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) 
     ; 

check-out this sql fiddle per vedere il lavoro.

0

Supponiamo che il vostro tavolo che ha valori 1,2,3,4,5 si chiama list_of_values, e supponiamo che la tabella che contiene alcuni valori, ma ha la colonna nome come some_values, si può fare:

SELECT B.id,A.name 
FROM [list_of_values] AS B 
LEFT JOIN [some_values] AS A 
ON B.ID = A.ID 
+3

Il problema è che l'elenco dei valori non è in nessuna tabella.Credo che la mia domanda iniziale si riassuma in: come posso convertire una lista di valori arbitrari in una sottoquery che può essere usata in un 'join'? – uncoder

2

Bit in ritardo su questo, ma per Oracle si potrebbe fare qualcosa di simile per ottenere una tabella di valori:

SELECT rownum + 5 /*start*/ - 1 as myval 
FROM dual 
CONNECT BY LEVEL <= 100 /*end*/ - 5 /*start*/ + 1 

... E poi unirsi che al vostro tavolo:

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 
Problemi correlati