2010-07-08 11 views
8

Consente di prendere in considerazione Ho una tabella 'Tab', che ha una colonna 'Col'Query: trovare le righe che non appartengono a un elenco di valori

La tabella 'Tab' ha questi dati -

Col 
1 
2 
3 
4 
5 

Se ho un set di valori (2,3,6,7). Posso interrogare i valori che sono presenti nella tabella e l'elenco facendo causa la query

Select Col from Tab where col IN (2,3,6,7) 

Ma, se voglio restituire i valori della lista che non sono presenti nella tabella cioè solo (6,7) in questo caso. Quale query dovrei usare?

+0

Che tipo di RDBMS e versione siete attivi? –

+0

Nei commenti che sono stati aggiunti a varie risposte, vedo che si tratta di valori di stringa, non di numeri interi e che l'elenco di input contiene da qualche parte in un raggio di 70 valori. Stai cercando di scrivere una procedura memorizzata? Utilizzo di SQL generato dinamicamente? Query parametrizzata? Come ha chiesto Martin, con quale piattaforma DB e versione stai lavorando? Questo ci dirà con quale set di funzionalità dobbiamo lavorare. (XML, UDF, ecc.) Linq-> SQL è un'opzione? – Toby

+0

@ Martin Sto lavorando su SQL Server 2005. @Toby Sto solo cercando di usare una query sql per recuperare le righe che soddisfano le condizioni che ho menzionato nella domanda. – pavanred

risposta

3

Il problema che credo è che il tuo tentativo di trovare valori da te in dichiarazione. Quello che devi fare è trasformare la tua istruzione in in una tabella e quindi determinare quali valori sono diversi.

create table #temp 
(
value int 
) 

insert into #temp values 1 
insert into #temp values 2 
insert into #temp values 3 
insert into #temp values 4 

select 
id 
from 
#temp 
where 
not exists (select 1 from Tab where Col = id) 

Una migliore alternativa sarebbe quella di creare una funzione con valori di tabella per trasformare la vostra stringa delimitata da virgole in una tabella. Non ho alcun codice a portata di mano, ma dovrebbe essere facile da trovare su Google. In tal caso, dovrai solo utilizzare la sintassi di seguito.

select 
id 
from 
dbo.SplitStringToTable('2,3,6,7') 
where 
not exists (select 1 from Tab where Col = id) 

Spero che questo aiuti

+0

Qui ho usato un esempio per semplicità. In realtà ho a che fare con circa 70 valori. Scrivere 70 istruzioni di inserimento non è davvero pratico. Mi chiedo se c'è un modo più semplice per farlo. Grazie comunque per la risposta. – pavanred

+0

Come si determinano i valori? – Wade73

+1

mi dispiace ho aggiunto il commento prima di provare l'ultima parte della risposta, ad esempio creare una funzione con valori di tabella per trasformare una stringa separata da virgola in una tabella. Ho provato questo ora diventa semplice una volta ho ottenuto l'elenco dei valori in una tabella. Grazie. – pavanred

0

Un metodo è

declare @table table(col int) 
insert into @table 
select 1 union all 
select 2 union all 
select 3 union all 
select 4 union all 
select 5 


declare @t table(col int) 
insert into @t 
select 2 union all 
select 3 union all 
select 6 union all 
select 7 

select t1.col from @t as t1 left join @table as t2 on t1.col=t2.col 
where t2.col is null 
2

Un modo potrebbe essere quello di utilizzare una tabella temporanea:

DECLARE @t1 TABLE (i INT) 
INSERT @t1 VALUES(2) 
INSERT @t1 VALUES(3) 
INSERT @t1 VALUES(6) 
INSERT @t1 VALUES(7) 

SELECT i FROM @t1 WHERE i NOT IN (Select Col from Tab) 
+0

+1 per aver rubato la mia risposta :) – Wade73

+0

Ho usato un esempio qui per semplicità. In realtà ho a che fare con circa 70 valori. Scrivere 70 istruzioni di inserimento non è davvero pratico. Mi chiedo se c'è un modo più semplice per farlo. Grazie comunque per la risposta. – pavanred

3

Uno SQL metodo Server 2008

SELECT N FROM (VALUES(2),(3),(6),(7)) AS D (N) 
EXCEPT 
Select Col from Tab 

o SQL Server 2005

DECLARE @Values XML 

SET @Values = 
'<r> 
    <v>2</v> 
    <v>3</v> 
    <v>6</v> 
    <v>7</v> 
</r>' 


SELECT 
    vals.item.value('.[1]', 'INT') AS Val 
FROM @Values.nodes('/r/v') vals(item) 
EXCEPT 
Select Col from Tab 
+0

+1 per l'utilizzo delle ultime tecniche – Wade73

0

Hai una tabella [numeri] nel tuo database? (Vedi Why should I consider using an auxiliary numbers table?)

SELECT 
    [Tab].* 
FROM 
    [numbers] 
    LEFT JOIN [Tab] 
     ON [numbers].[num] = [Tab].[Col] 
WHERE 
    [numbers].[num] IN (2, 3, 6, 7) 
    AND [Tab].[Col] IS NULL 
+0

Grazie per la risposta. Non ero a conoscenza di questo. Ma, ho usato un esempio qui per semplicità. In realtà mi sto occupando di varchar e non di numeri. – pavanred

0

penso che ci sono molti modi per raggiungere tale scopo, qui è uno.

SELECT a.col 
FROM 
    (SELECT 2 AS col UNION ALL SELECT 3 UNION ALL SELECT 6 UNION ALL SELECT 7) AS a 
WHERE a.col NOT IN (SELECT col FROM Tab) 
0

in ritardo alla festa ...

SELECT 
    '2s' = SUM(CASE WHEN Tab.Col = 2 THEN 1 ELSE 0 END), 
    '3s' = SUM(CASE WHEN Tab.Col = 3 THEN 1 ELSE 0 END), 
    '6s' = SUM(CASE WHEN Tab.Col = 6 THEN 1 ELSE 0 END), 
    '7s' = SUM(CASE WHEN Tab.Col = 7 THEN 1 ELSE 0 END) 
FROM 
(SELECT 1 AS Col, 'Nums' = 1 UNION SELECT 2 AS Col,'Nums' = 1 UNION SELECT 3 AS Col,  'Nums' = 1 UNION SELECT 4 AS Col, 'Nums' = 1 UNION SELECT 5 AS Col, 'Nums' = 1) AS Tab 
GROUP BY Tab.Nums 

BTW, il mio dà anche i conteggi di ciascuna, utili in caso di necessità. Come se stessimo controllando un elenco di prodotti contro ciò che hai nell'inventario. Anche se puoi scrivere un perno per quello meglio, solo non so quanto sia fuori di testa.

Problemi correlati