2016-05-12 2 views
0

Ich verwende mysql.Finden Sie fehlende Werte in einer Spalte aus einer Menge (mysql)

Ich habe eine Tabelle, die eine Spalten-ID hat.

Sagen wir, ich habe einen Eingabesatz von IDs. Ich möchte wissen, welche alle IDs in der Tabelle fehlen.

Wenn die Menge "ida", "idb", "idc" ist und die Tabelle nur "idb" enthält, sollte der zurückgegebene Wert "ida", "idc" sein.

Ist dies mit einer einzigen SQL-Abfrage möglich? Wenn nicht, was ist der effizienteste Weg, dies auszuführen?

Beachten Sie, dass ich gespeicherte Prozedur nicht verwenden darf.

+1

Sie können dies einfach in Ihrem Anwendungscode tun. Welche Programmiersprache verwenden Sie? – tadman

+0

Klingt wie 'WHERE id NICHT IN ('ida', 'idb', 'idc')' –

+0

Art von 'SELECT a.id FROM input_set eine LINKE JOIN-Tabelle b ON a.id = b.id WO b.id ist NULL – Serg

Antwort

2

MySQL gibt nur Zeilen zurück, die existieren. Um fehlende Zeilen zurückzugeben, müssen Sie zwei Tabellen haben.

Die erste Tabelle kann temporär (sitzungs-/verbindungsspezifisch) sein, sodass mehrere Instanzen gleichzeitig ausgeführt werden können.

create temporary table tmpMustExist (text id); 
insert into tmpMustExist select "ida"; 
insert into tmpMustExist select "idb"; 
-- etc 

select a.id from tmpMustExist as a 
    left join table b on b.id=a.id 
    where b.id is null; -- returns results from a table that are missing from b table. 

Ist dies möglich, mit einer einzigen SQL-Abfrage?

Nun, ja ist es. Lassen Sie mich dazu arbeiten, zuerst mit einem union all die select Aussagen zu kombinieren.

create temporary table tmpMustExist (text id); 
insert into tmpMustExist select "ida" union all select "idb" union all select "etc..."; 
select a.id from tmpMustExist as a left join table as b on b.id=a.id where b.id is null; 

Bitte beachte, dass ich union all verwenden, die ein bisschen schneller als union ist, weil es über die Deduplizierung überspringt.

Sie können create table ... select verwenden. Ich mache das häufig und mag es wirklich. (Es ist eine gute Möglichkeit, einen Tisch und zu kopieren, aber es wird Indizes löschen.)

create temporary table tmpMustExist as select "ida" union all select "idb" union all select "etc..."; 
select a.id from tmpMustExist as a left join table as b on b.id=a.id where b.id is null; 

Und schließlich können Sie verwenden, was eine „abgeleitete“ Tabelle nennt das Ganze in einem einzigen, tragbaren wählen zu bringen Erklärung.

select a.id from (select "ida" union all select "idb" union all select "etc...") as a left join table as b on b.id=a.id where b.id is null; 

Hinweis: Die as Schlüsselwort ist optional, aber stellt klar, was ich mit a und b mache. Ich bin einfach nur kurze Namen zu schaffen, um in den join und select Feldlisten

0
//you can pass each set string to query 
//pro-grammatically you can put quoted string 
//columns must be utf8 collation 

select * from 
(SELECT 'ida' as col 
union 
SELECT 'idb' as col 
union 
SELECT 'idc' as col) as setresult where col not in (SELECT value FROM `tbl`) 
0

Es gibt einen Trick verwendet werden. Sie können entweder eine Tabelle mit erwarteten Werten erstellen oder Sie können die Vereinigung mehrerer Auswahlmöglichkeiten für jeden Wert verwenden.

Dann müssen Sie alle Werte finden, die sich im Etalon befinden, aber nicht in der getesteten Tabelle.

CREATE TABLE IF NOT EXISTS `single` (
    `id` varchar(10) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `single` (`id`) VALUES 
('idb'); 

SELECT a.id FROM (
    SELECT 'ida' as id 
    UNION 
    SELECT 'idb' as id 
    UNION 
    SELECT 'idc' AS id 
) a WHERE a.id NOT IN (SELECT id FROM single) 
Verwandte Themen