Toon posts:

[MySQL] SELECT veld WHERE value [niet in] andere tabel

Pagina: 1
Acties:

Verwijderd

Topicstarter
Goedendag,

Ik heb 2 tabellen, questions en user_answers. In questions heb ik q_id, en ik user_answers heb ik ua_id, ua_q_id, ua_u_id (dus het unieke id, question id waar het bij hoort en de user waar het bij hoort),

Nu wil ik uit de tabel questions de rijen halen, waarvoor er geen waarde van q_id in users_answers zit. Ofwel; de vragen die de user nog niet heeft ingevuld.

Ik heb al wat zitten proberen met joins, maar ik heb het gevoel dat ik er daarmee niet uit ga komen.

Wie weet hoe het moet, of wie kan me in de goede richting schoppen?

Alvast tnx,
Roemer

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 20:30

glashio

C64 > AMIGA > PC

Dat is een LEFT JOIN :
code:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT
  q.*
FROM
  questions q
LEFT JOIN
  user_answers a
ON
  a.ua_q_id = q.q_id
WHERE
  q.q_id IS NULL
AND
  a.ua_u_id = 85

Je zal nu de vragen terug krijgen die de user ( userid = 85 ) nog niet ingevuld heeft :)

[ Voor 9% gewijzigd door glashio op 08-06-2005 18:03 ]

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing


Verwijderd

Topicstarter
heel erg bedankt voor je reactie, maar helaas werkt het niet..

Ik heb het ook geprobeert met
WHERE a.ua_q_id IS NULL (dat leek mij logischer), maar dat werkte ook niet...

iemand nog idee-en?

Verwijderd

zoiets?

code:
1
2
3
4
5
6
7
8
select *
from questions
where q_id not in
(
select ua_q_id
from user_answers
where ua_u_id = 85
)

[ Voor 116% gewijzigd door Verwijderd op 08-06-2005 21:20 ]


  • mosymuis
  • Registratie: Maart 2002
  • Laatst online: 07-01 19:39
Verwijderd schreef op woensdag 08 juni 2005 @ 19:32:
Ik heb het ook geprobeert met
WHERE a.ua_q_id IS NULL (dat leek mij logischer), maar dat werkte ook niet...
Dát zou toch echt moeten werken. Zie: clique. Velo's oplossing kan ook, als je MySQL >=4.1 draait.

//edit
linkje gefixt

[ Voor 12% gewijzigd door mosymuis op 09-06-2005 13:20 ]


Verwijderd

Whaaaa.. tis een Not Exists query als je het mij vraagt:

SQL:
1
2
3
4
select q.* from questions q
where not exists
  (select ua_id from user_answers
  where ua_q_id = q_id and ua_u_id = 85)


Deze hebben als bijkomend voordeel dat ze veeeeel rapper zijn dan Not In queries

[ Voor 18% gewijzigd door Verwijderd op 09-06-2005 10:20 ]


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Volgens mij kun je het beter met een join oplossen. Heb zo geen query voor handen maar de not in select* queries hebben echt K performance, niet aan te raden dus! Helemaal niet voor beetje grote tabellen.

If you are not wiping out you are nog pushing enough...


Verwijderd

Topicstarter
De mysql versie waar het script op moet komen is lager dan 4.1, dus subqueries zullen niet werken.

Ik heb nog wat met de eerste query zitten klooien (met ua.ua_q_id IS NULL), en ben er achter gekomen dat het wel werkt als ik
AND ua.ua_u_id = 85
weg laat (ja, 85 aangepast ;)). Maar als ik nu 2 gebruikers heb, dan ziet de 2e gebruiker dus alleen de niet ingevulde vragen van de eerste gebruiker.

Ik vind het maar vaag...

Weet iemand wat hier dan de oplossing voor is?
Bedankt allemaal trouwens voor het meedenken!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Het probleem is dat je UserId in de tabel staat waarvan je wilt controleren of er antwoorden zijn. Je wilt kijken of user_answers "leeg" is voor een bepaalde user, maar de userid staat ook in diezelfde tabel. Je kunt dus niet de IS NULL gebruiken icm met een WHERE. Immers als het record nog niet bestaat in de user_answers tabel, kun je ook niet controleren of het userId 85 is. Ik leg het een beetje krom uit, maar ik denk dat je me wel snapt.

Heb je nog een andere tabel met users? ( een stamtabel met alle users bijvoorbeeld. )

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
na 2x lezen begin ik je te begrijpen ;)

Ik heb idd nog een user tabel, met oa u_id. Hoe zou ik die dan moeten gebruiken?

Verwijderd

MaxxRide schreef op donderdag 09 juni 2005 @ 10:53:
Volgens mij kun je het beter met een join oplossen. Heb zo geen query voor handen maar de not in select* queries hebben echt K performance, niet aan te raden dus! Helemaal niet voor beetje grote tabellen.
Kun je lang en breed over discussieren. Met een goede query optimiser maakt het echter niets uit. Die kiest namelijk hetzelfde executiepad. Met een slechte query optimiser kan je verschillen vinden maar wat sneller is hangt dan weer sterk van de dataset (en de optimiser) af.

Wat MySQL betreft. Schaar die maar onder de slechte query optimisers. Kan best dat daar de code voor de outer join wat verder ontwikkeld is. Dat is schijnbaar normaal bij MySQL. Nieuwe features werken niet naar behoren of zijn uiterst traag. Maar principieel is er geen reden waarom twee uitwisselbare queries verschillende performance zouden moeten hebben. Het is juist de taak van de query optimiser om dat soort "problemen" glad te strijken. Uiteindelijk zal zelfs MySQL dat soort zaken ook naar behoren gaan doen. (En nee, ik ben geen MySQL fan. :) )

[ Voor 33% gewijzigd door Verwijderd op 09-06-2005 13:52 ]


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Als alle users alle vragen moeten beantwoorden zou je zoiets krijgen:
code:
1
2
3
4
5
SELECT * 
FROM Questions Q
CROSS JOIN Users U
LEFT OUTER JOIN User_Answers UA ON Q.q_id = UA.ua_q_id AND UA.ua_u_id = U.u_id
WHERE U.u_id = 1 AND UA.ua_u_id IS NULL


Eerst een crossjoin om alle combinaties van users en vragen te krijgen, dan de outer join op vraag, en user om de nog niet beantwoorde te krijgen.

Ik weet niet de exacte crossjoin syntax van mySQL, het kan zijn dat je gewoon een join moet gebruiken zonder join criteria, zoiets:

SELECT *
FROM Questions
INNER JOIN Users

Kun je niet wat duidelijker kolomnamen maken, ik moest steeds 3 x kijken

Oops! Google Chrome could not find www.rijks%20museum.nl

Pagina: 1