INTERSECTEN in MySQL

Ik heb twee tabellen, records en gegevens. records heeft meerdere velden (voornaam, achternaam, etc.). Elk van deze velden is een externe sleutel voor de gegevenstabel waarin de werkelijke waarde is opgeslagen. Ik moet zoeken op meerdere recordvelden.

Hieronder staat een voorbeeldquery die INTERSECT gebruikt, maar ik heb er een nodig die in MySQL werkt.

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"

Bedankt voor alle hulp.


Antwoord 1, autoriteit 100%

U kunt een inner join gebruiken om te filteren op rijen die een overeenkomende rij in een andere tabel hebben:

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"

Een van de vele andere alternatieven is een in-clausule:

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'
)

Antwoord 2, autoriteit 48%

Ik denk dat deze methode veel gemakkelijker te volgen is, maar er is een beetje overhead aan verbonden omdat je aanvankelijk veel dubbele records laadt. Ik gebruik het in een database met ongeveer 10000-50000 records en kruist meestal ongeveer 5 zoekopdrachten en de prestaties zijn acceptabel.

Het enige wat u hoeft te doen is “UNION ALL” alle zoekopdrachten die u wilt laten kruisen en zien welke u elke keer krijgt.

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 

Dus als we in beide zoekopdrachten hetzelfde record krijgen, is het aantal 2 en wordt dit in de laatste omhullende zoekopdracht opgenomen.


Antwoord 3, autoriteit 15%

Gebruik in plaats daarvan joins:

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 zijn enkele testgegevens:

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');

Verwacht resultaat:

2

De testgegevens zijn waarschijnlijk niet nuttig voor de poster, maar kunnen nuttig zijn voor kiezers die oplossingen willen controleren om te zien of ze correct werken, of mensen die antwoorden willen indienen zodat ze hun eigen antwoorden kunnen testen.

p>


Antwoord 4, autoriteit 6%

Ik ben een beetje laat voor het feest, maar ik denk dat de schoonste en beste manier om INTERSECTvolledig te emuleren, is:

SELECT * FROM
( SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john" ) x1
NATURAL JOIN
( SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith" ) x2

Antwoord 5, autoriteit 3%

Een algemene vervanging voor INTERSECT in MYSQL is inner join:

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)

Of specifiek voor jouw geval:

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)

Antwoord 6, autoriteit 3%

SELECT t.id FROM table t WHERE NOT EXISTS (SELECT t2.id, FROM table2 t2 WHERE t2.id = t1.id)

https://dev .mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html


Antwoord 7

Aangezien Mysql INTERSECT niet ondersteunt, heeft u mogelijk 2 alternatieven: inner joinen in. Dit is een oplossing met in:

SELECT records.id FROM records, data 
WHERE data.id = records.firstname AND data.value = "john"
    AND records.id in (SELECT records.id FROM records, data 
    WHERE data.id = records.lastname AND data.value = "smith);

Other episodes