MySQL Joins

Pagina: 1
Acties:

  • Niakmo
  • Registratie: Juni 2001
  • Laatst online: 10-02-2024
Ik heb het volgende probleem

ik heb twee tabellen:
1. unchecked (hierin staan pagina's die gecontroleerd moeten worden)
2. checks (in deze tabel word bij elke controle een record toegevoegd van welke pagina gecontroleerd is en door wie)

nu wil ik uit de unchecked tabel een pagina halen die door een bepaalde persoon nog niet gecontroleerd is.

daarvoor gebruikte ik de volgende query
SQL:
1
2
3
4
SELECT unchecked.id, unchecked.page_id
FROM checks, unchecked
WHERE unchecked.page_id != checks.page_id 
AND checks.uid =de_user_in_kwestie 

dus als ik in een unchecked tabel heb met de volgende inhoud
code:
1
2
3
4
5
6
id   page_id
1    1
2    2
3    3
4    4
5    5

en een lege checks tabel hoor ik alle 5 de rijen gereturend te krijgen, helaas gebeurd dit niet.

zodra ik in de checks tabel een aantal rijen toevoeg
code:
1
2
3
id   page_id   uid
1    2         2
2    3         3

als ik nu voor de uid in de quey 2 invul krijg ik mooi de paginas 1 3 4 en 5 want pagina 2 is door de user al gecheckt. hij neemt wel pagina 3 mee aangezien die alleen door een andere user is gechecked en niet door hem

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:33
Probeer eens goed na te denken over wat je huidige query nu precies doet. De basis van elke query is het carthesisch product van de tabellen waaruit je selecteert. Je selecteert dus alle paren van rijen uit de twee tabellen in de FROM clause, en daarvan alleen die paren die aan je WHERE clause voldoen.

Als je dat met de hand uitwerkt zie je al snel dat er niets van je WHERE clause klopt. In jouw voorbeeldje gaat het toevallig goed, maar het gaat al mis zodra één gebruiker meer dan één pagina gecheckt heeft. Als ik die rij met uid 3 in uid 2 verander, wordt het zo:
unchecked.page_idchecks.page_idchecks.uidgeselecteerd
122*
222
322*
422*
522*
132*
232*
332
432*
532*

Van alles dubbel dus!

Wat je moet doen, is eerst de rijen uit de eerste tabel koppelen aan de tweede en dan de gewenste resultaten selecteren:
SQL:
1
2
3
4
SELECT unchecked.id, unchecked.page_id 
FROM unchecked
LEFT JOIN checks ON checks.uid = <uid> AND checks.page_id = unchecked.page_id
WHERE checks.page_id IS NULL

[ Voor 36% gewijzigd door Soultaker op 07-08-2006 04:14 ]


  • Niakmo
  • Registratie: Juni 2001
  • Laatst online: 10-02-2024
dat is hem inderdaad ik heb tijdens mijn zoektocht nog deze dingen gevonden:

hier hadden ze het over de MINUS JOIN, dat was eigenlijk wat ik nodig had, maar deze is er niet in MySQL voorzover ik het weet.

dus na wat google vond ik inderdaad die oplossing

  • Stamgastje
  • Registratie: April 2003
  • Laatst online: 02-02-2020
Een minus query kan ook zo uitgevoerd worden:
SQL:
1
SELECT u.id, u.page_id FROM unchecked AS u WHERE u.page_id NOT IN (SELECT c.page_id FROM checked AS c WHERE c.uid = de_user_in_kwestie)

Dit is een vrij letterlijke vertaling van de query (spreektaal -> SQL), maar de JOIN operatie is misschien alleen wat efficiënter.

(Overigens werkt deze query pas vanaf MySQL v4.1 of hoger, 4.0 en lager kunnen niet met subqueries overweg.)

[ Voor 22% gewijzigd door Stamgastje op 07-08-2006 16:11 ]