Hallo,

Ik zit met het volgende probleem:

Ik heb 3 tabellen:

------fietsverkoper--------
id
name
...
...

------fietssoort-------
id
name
...
...

------interactie------
id
soortid
verkoperid



Nu wil ik door een soort fiets in te vullen alle fabrikanten krijgen die die soort verkopen. Dat wil nog prima:

SELECT
	fietsverkoper.name
FROM
	fietsverkoper
INNER JOIN
		interactie
	ON
		fietsverkoper.id = interactie.verkoperid
WHERE
	interactie.soortid = 1


Maar nu moet het zo dat mensen meerdere fietssoorten kunnen selecteren, en dat alleen de verkopers die alle fietssoorten die zijn geselecteerd uit de query komen.

Ik hoop dat het zo duidelijk is.
Alvast bedankt:D
Dan moet je gewoon de WHERE uitbreiden, heeft verder weinig met de join temaken:


WHERE interactie.soortid = 1 AND interactie.soortid=2
enz.. Dat zou moeten werken voor zover ik kan overzien, ik ken je tabelindeling natuurlijk niet, maar als je nu op 1 fietssoort selecteerd, dan kan dat ook op meerdere.
Nee, dat werkt niet, want dan vraag je eigenlijk of 1 veld twee verschillende waardes heeft.
Ik zal even zeggen hoe de tabelindeling is:


----fietsverkoper----
id	name

1	piet
2	jan
3	kees

----fietssoort-----
id	name

1	merk1
2	merk2
3	merk3

----interactie-----
id	soortid	verkoperid

1	1		1
2	1		2
3	2		2
4	2		3
5	3		1
6	3		3




Ik hoop dat het nu iets duidelijker is:D
*BUMP*
Bumpen pas na 24 uur!

Maar goed, ervan uitgaande dat het op een of andere manier mogelijk moet zijn, ben ik maar even gaan puzzelen.

Het probleem waar je tegen aan loopt, is dat je alleen de records op moet halen waarbij er in de koppeltabel een record bestaat voor alle geselecteerde keuzes. Nu kun je zoals je zelf al terecht opmerkte niet een oplossing gebruiken als:

... WHERE soortid = 1 AND soortid = 2

Aangezien soortid natuurlijk nooit tegelijk 2 dezelfde waardes kan hebben. Wel kun je alle records ophalen die aan 1 (of meer) van de geselecteerde waarden voldoen. Om nu te controleren of een bepaalde verkoper ook alle soorten verkoopt (lees: voor elke geselecteerd soort een record in de koppeltabel bestaat), zou je het aantal records per verkoper moeten tellen en dat vervolgens moeten vergelijken met het aantal soorten dat door de gebruiker gekozen is.

De brongegevens waarmee ik aan de slag ben gegaan:

mysql> SELECT * FROM verkopers;
+----+------+
| id | naam |
+----+------+
| 1  | jan  |
| 2  | kees |
| 3  | piet |
+----+------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM soort;
+----+-------+
| id | soort |
+----+-------+
| 1  | merk1 |
| 2  | merk2 |
| 3  | merk3 |
+----+-------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM verkoper_soort;
+----+-----+-----+
| id | vid | sid |
+----+-----+-----+
| 1  | 1   | 1   |
| 2  | 1   | 2   |
| 3  | 1   | 3   |
| 4  | 2   | 2   |
| 5  | 2   | 3   |
| 6  | 3   | 1   |
| 7  | 3   | 2   |
| 8  | 3   | 3   |
+----+-----+-----+
8 rows in set (0.00 sec)

De variabelen die je nu vooraf moet kennen zijn ten eerste de keuzes die door de gebruiker gemaakt zijn in de vorm van het soortid en het totaal aantal soorten dat door de gebruiker geselecteerd is.

In dit voorbeeld ga ik ervan uit dat een gebruiker op zoek is naar een verkoper die zowel de fietsen van merk1 en merk3 verkoopt. En nu dan de query die dit alles mogelijk maakt:

SELECT
	verkopers.naam 
FROM
	verkopers,
	(SELECT
		vid,
		COUNT(*) AS totaal
	FROM 
		verkoper_soort 
	WHERE 
		sid IN (1, 3) 
	GROUP BY
		vid
	) AS verkoper_soort_result
WHERE
	verkoper_soort_result.vid = verkopers.id
AND
	verkoper_soort_result.totaal = 2;

Je ziet dat er op 2 plaatsen variabelen ingevuld dienen te worden. Binnen de IN() vul je de geselecteerde soorten gescheiden door een komma in en op de plaats van de 2 komt het totaal aantal geselecteerde soorten te staan.

Om aan te tonen dat dit werkt, ook nog 3 voorbeeldjes:

mysql> SELECT verkopers.naam FROM verkopers, (SELECT vid, COUNT(*) AS totaal FROM verkoper_soort WHERE sid IN (1,3) GROUP BY vid) AS verkoper_soort_result WHERE verkoper_soort_result.vid = verkopers.id AND verkoper_soort_result.totaal = 2;
+------+
| naam |
+------+
| jan  |
| piet |
+------+
2 rows in set (0.00 sec)

mysql> SELECT verkopers.naam FROM verkopers, (SELECT vid, COUNT(*) AS totaal FROM verkoper_soort WHERE sid IN (1,2,3) GROUP BY vid) AS verkoper_soort_result WHERE verkoper_soort_result.vid = verkopers.id AND verkoper_soort_result.totaal = 3;
+------+
| naam |
+------+
| jan  |
| piet |
+------+
2 rows in set (0.00 sec)

mysql> SELECT verkopers.naam FROM verkopers, (SELECT vid, COUNT(*) AS totaal FROM verkoper_soort WHERE sid IN (2) GROUP BY vid) AS verkoper_soort_result WHERE verkoper_soort_result.vid = verkopers.id AND verkoper_soort_result.totaal = 1;
+------+
| naam |
+------+
| jan  |
| kees |
| piet |
+------+
3 rows in set (0.00 sec)


ps. Wie weet is er een minder omslachtige manier. Ik ben benieuwd of die hier dan boven tafel komt.
Geniaal. Ik wist niet dat dit soort constructies konden.
Misschien kan het inderdaad nog efficiƫnter, maar ik vindt het zo ook prima, want ik was al geneigd om met meerdere querys te gaan prutsen.
Persoonlijk had ik denk ik eerder voor zo'n constructie gekozen:
SELECT
    verkopers.naam 
FROM
    verkopers
INNER JOIN
    (SELECT
        vid,
        COUNT(*) AS totaal
    FROM 
        verkoper_soort 
    WHERE 
        sid IN (1, 3) 
    GROUP BY
        vid
    ) AS verkoper_soort_result
    ON
        verkoper_soort_result.vid = verkopers.id
WHERE
    verkoper_soort_result.totaal = 2;

Maar dat is ieder zijn mening:D
In ieder geval hartstikke bedankt!
@blauwtje

Jou constructie is hetzelfde als die van Blanche, ware het niet dat jij de tekst INNER JOIN gebruikt. De WHERE verkoper_soort_result.vid=verkopers.id betekend in dit geval een join op die kolommen.
Het verschil in beide query's is dus eigenlijk 0,0 alleen de schrijfwijze is een beetje anders.

Reageren