2012-05-22 19 views
17

Supponiamo la seguente:creare una tabella in linea di SQL al volo (per una esclusione di sinistra join)

Tabella A

id | value 
---------- 
1 | red 
2 | orange 
5 | yellow 
10 | green 
11 | blue 
12 | indigo 
20 | violet 

Ho una lista di id (10, 11, 12, 13 , 14) che può essere usato per cercare id in questa tabella. Questo elenco di ID è generato nel mio frontend.

Usando esclusivamente SQL, devo selezionare gli ID da questo elenco (10, 11, 12, 13, 14) che non hanno voci nella Tabella A (che si unisce alla colonna 'id'). Il risultato dovrebbe essere il risultato di id 13 e 14.

Come posso realizzare questo utilizzando solo SQL? (Inoltre, vorrei evitare di utilizzare una stored procedure se possibile)

L'unico approccio che posso pensare è qualcosa che creerebbe una tabella SQL in linea al volo per contenere temporaneamente la mia lista di id. Tuttavia, non ho idea di come farlo. È possibile? C'è un modo migliore?

Grazie! :)

+0

Questo non è molto chiaro. Se i tuoi ID non sono in un altro tavolo, non c'è nulla da aggiungere. – Cfreak

+0

Esattamente. :) Qui sta il problema! – rinogo

+0

Cosa c'è di sbagliato in 'NOT IN ()'? – Cfreak

risposta

18

È possibile creare un "tavolo in linea" con una UNION subquery:

(
      SELECT 10 AS id 
    UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 
    -- etc. 
) AS inline_table 
+0

Questo sarà un problema se la mia lista è in realtà di poche centinaia di elementi (invece di 5 elementi come nella domanda)? – rinogo

+0

@rinogo: Beh, renderebbe la tua query abbastanza lunga (il che potrebbe significare che ci vorrà un po 'prima di analizzarla), ma non sono a conoscenza di problemi inerenti che potrebbero causare. – eggyal

+2

@rinogo: con elenchi molto grandi è possibile raggiungere il limite di "max_allowed_packet' che non consente di inviare la query, anche se richiede centinaia di migliaia di record con impostazioni predefinite. – Quassnoi

5
CREATE TEMPORARY TABLE ids (id INT NOT NULL PRIMARY KEY); 

INSERT 
INTO ids 
VALUES 
(10), 
(11), 
(12), 
(13), 
(14); 

SELECT * 
FROM ids 
WHERE id NOT IN 
     (
     SELECT id 
     FROM a 
     ); 
+0

ma, non funzionerà per le query parallele! –

+0

@mortezakavakebi: cosa intendi? – Quassnoi

+0

creazione di una tabella non è una sessione di base. quando diversi utenti chiamano un url contenente questa query, crea conflitti nella tabella "id". –

33

Si può fare questo da SQL Server 2008 in poi con un valore di tabella costruttore.

SELECT * FROM (
    VALUES(1, 'red'), 
     (2, 'orange'), 
     (5, 'yellow'), 
     (10, 'green'), 
     (11, 'blue'), 
     (12, 'indigo'), 
     (20, 'violet')) 
    AS Colors(Id, Value) 

Maggiori informazioni qui: Table Value Constructor

+5

Sfortunatamente questa domanda è contrassegnata con 'mysql', non' sql-server'. – trincot

+3

Fortunatamente per me ho ancora cliccato su di esso e ho trovato questo – Jonesopolis

Problemi correlati