2012-05-22 8 views
17

Przyjmijmy następujące:Utwórz tabelę inline SQL w locie (za wyjątkiem lewej przyłączyć)

Tabela A

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

Mam listę identyfikatorów (10, 11, 12, 13 , 14), które można wykorzystać do wyszukania identyfikatorów w tej tabeli. Ta lista identyfikatorów jest generowana w moim interfejsie.

Używając czysto SQL, muszę wybrać identyfikatory z tej listy (10, 11, 12, 13, 14), które nie mają wpisów w Tabeli A (łączenie w kolumnie "identyfikator"). Rezultatem powinien być zestaw wyników id 13 i 14.

Jak mogę to zrobić, używając tylko SQL? (Poza tym chciałbym uniknąć stosowania procedury przechowywanej, jeśli to możliwe).

Jedyne podejście, jakie mogę wymyślić, to coś, co spowoduje utworzenie wbudowanej tabeli SQL w locie, aby tymczasowo zatrzymać moją listę identyfikatorów. Jednak nie mam pojęcia, jak to zrobić. czy to możliwe? Czy istnieje lepszy sposób?

Dzięki! :)

+0

To nie jest bardzo jasne. Jeśli Twoje identyfikatory nie znajdują się w innej tabeli, nie ma nic do przyłączenia się. – Cfreak

+0

Dokładnie. :) Na tym polega problem! – rinogo

+0

Co jest nie tak z 'NOT IN ()'? – Cfreak

Odpowiedz

18

Można utworzyć tabelę "inline" z UNION podzapytaniu:

(
      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

Czy to będzie problem, jeśli moja lista ma kilkaset pozycji (zamiast 5 pozycji, jak w pytaniu)? – rinogo

+0

@rinogo: Cóż, to sprawi, że zapytanie będzie dość długie (co może oznaczać, że zajmie trochę czasu analizowanie), ale nie jestem świadomy żadnych nieodłącznych problemów, które mogą powodować. – eggyal

+2

@rinogo: z naprawdę dużymi listami można nacisnąć limitu 'max_allowed_packet', który nie pozwoli na przesłanie zapytania, chociaż wymaga setek tysięcy rekordów z ustawieniami domyślnymi. – 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

, ale nie będzie działać dla równoległych zapytań! –

+0

@mortezakavakebi: co masz na myśli? – Quassnoi

+0

tworzenie tabeli nie jest podstawą sesji. gdy różni użytkownicy wywołują adres URL zawierający ten Query powoduje konflikt w tabeli "ids". –

33

Można to zrobić z SQL Server 2008 roku używając wartości stołowego konstruktor.

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

Więcej informacji tutaj: Table Value Constructor

+5

Niestety to pytanie jest oznaczone tagiem 'mysql', a nie' sql-server'. – trincot

+3

Na szczęście dla mnie wciąż kliknąłem i znalazłem to – Jonesopolis