2010-02-19 5 views
27

Ich habe zwei Tabellen, Datensätze und Daten. Datensätze haben mehrere Felder (Vorname, Nachname usw.). Jedes dieser Felder ist ein Fremdschlüssel für die Datentabelle, in der der tatsächliche Wert gespeichert ist. Ich muss nach mehreren Datensatzfeldern suchen.INTERSECT in MySQL

Unten ist eine Beispielabfrage mit INTERSECT, aber ich brauche eine, die in MySQL funktioniert.

SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john" 
INTERSECT 
SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith" 

Vielen Dank für jede Hilfe.

+1

einen Blick auf diese: http://www.codinghorror.com/ blog/2007/10/a-visuelle-erklärung-von-sql-joins.html –

+0

@Mike Atlas: Dies hat nichts mit Joins zu tun. Es kann so gelöst werden, aber Jeffs Blogbeitrag ist nicht relevant. – Aaronaught

+1

Ja, es hat mit Joins zu tun und ist relevant. Es erklärt, welcher SQL-Join einer Schnittmenge zweier Daten entspricht (innerer Join). Daraus sollte Jeremy in der Lage sein, die Standard-SQL-Syntax für "Kreuzung" herauszufinden. Ich habe dies nur als Kommentar gepostet, da andere die genaue Antwort unten gegeben haben. –

Antwort

23

Sie können eine innere JOIN für Zeilen, die eine passende Zeile in einer anderen Tabelle filtern haben:

SELECT DISTINCT records.id 
FROM records 
INNER JOIN data d1 on d1.id = records.firstname AND data.value = "john" 
INNER JOIN data d2 on d2.id = records.lastname AND data.value = "smith" 

Eine von vielen anderen Alternativen ist eine in Klausel:

SELECT DISTINCT records.id 
FROM records 
WHERE records.firstname IN (
    select id from data where value = 'john' 
) AND records.lastname IN (
    select id from data where value = 'smith' 
) 
+1

Ich mag die 'WHERE' Klausel Idee die beste – scottyseus

5

Verwendung schließt sich stattdessen :

SELECT records.id 
FROM records 
JOIN data AS D1 ON records.firstname = D1.id 
JOIN data AS D2 ON records.lastname = D2.id 
WHERE D1.value = 'john' and D2.value = 'smith' 

Hier sind einige Testdaten:

CREATE TABLE records (id INT NOT NULL, firstname INT NOT NULL, lastname INT NOT NULL); 
INSERT INTO records (id, firstname, lastname) VALUES 
(1, 1, 1), 
(2, 1, 2), 
(3, 2, 1), 
(4, 2, 2); 

CREATE TABLE data (id INT NOT NULL, value NVARCHAR(100) NOT NULL); 
INSERT INTO data (id, value) VALUES 
(1, 'john'), 
(2, 'smith'); 

Erwartetes Ergebnis:

2 

Die Daten Test wahrscheinlich nicht nützlich für das Plakat ist, könnte aber für die Wähler nützlich sein, die Lösungen zu überprüfen, um zu sehen möchten, dass sie richtig oder Menschen arbeiten, die wollen Antworten einreichen, damit sie ihre eigenen Antworten testen können.

8

Ich denke, diese Methode ist viel einfacher zu folgen, aber es ist ein wenig Aufwand verbunden, weil Sie viele doppelte Datensätze zunächst laden. Ich verwende es in einer Datenbank mit ungefähr 10000-50000 Datensätzen und überschneidet sich in der Regel mit etwa 5 Abfragen und die Leistung ist akzeptabel.

Alles, was Sie tun, ist "UNION ALL" jede der Abfragen, die Sie schneiden möchten und sehen, welche Sie jedes Mal bekommen.

SELECT * From (

    (Select data1.* From data1 Inner Join data2 on data1.id=data2.id where data2.something=true) 
    Union All 
    (Select data1.* From data1 Inner Join data3 on data1.id=data3.id where data3.something=false) 

) As tbl GROUP BY tbl.ID HAVING COUNT(*)=2 

Also, wenn wir denselben Datensatz in beiden Abfragen erhalten, ist es Zahl 2 sein wird, und die endgültige Wrap-around-Abfrage wird es umfassen.

0

Ein allgemeiner Ersatz für INTERSECT in MYSQL beitreten Innen ist:

SELECT DISTINCT * FROM 
(SELECT f1, f2, f3... FROM table1 WHERE f1>0) 
INNER JOIN 
(SELECT f1, f2, f3... FROM table2 WHERE f1>0) 
USING(primary_key) 

Oder für Ihren Fall speziell:

SELECT DISTINCT * FROM 
(SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john") query1 
INNER JOIN 
(SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith") query2 
USING (id) 
Verwandte Themen