[mysql] left join probleem met een 'behalve' label

Pagina: 1
Acties:

  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
Hey,

Ik heb een tabel met personen en een tabel met labels en een relatietabel tussen die twee.
Nu wil ik een query schrijven om iemand uit de personen tabel te krijgen die voldoet aan een label en die ook voldoet aan een behalve label.

Vb. select iedereen die een fiets heeft en die geen auto heeft.

Nu heb ik al erg veel gebrobeerd maar dit komt het beste in de buurt.
SELECT *
FROM persoon
LEFT JOIN rel ON ( persoon.id = rel.pid AND rel.vid =2 )


rel.vid =2 ->hierin geef ik dus de label aan die wel moet voldoen.
Nu krijg in een tabel terug waar dus die personen instaan die ik zoek die hebben pid=NULL. maar daar kan ik niet meer op zoeken in de where clause. Waarschijnlijk omdat ik die pid al heb aangeroepen bij de ON.

Heeft iemand een idee?
Lijkt me dat het wel vaker voorkomt deze situatie, maar kan het nergens vinden.

Gr daan

www.killyourdarlings.nl


Verwijderd

code:
1
2
3
4
SELECT *
FROM person
    INNER JOIN rel ON ( persoon.id = rel.pid)
WHERE rel.vid = 2

zoiets?

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 09:16

Dido

heforshe

Op voorwaarde dat subqueries geen probleem zijn, zoiets?
code:
1
2
3
4
5
6
7
8
SELECT *
  FROM persoon
  LEFT JOIN rel ON persoon.id = rel.pid
 WHERE rel.vid = 2
   AND persoon.id NOT IN (SELECT persoon.id
                          FROM persoon
                          LEFT JOIN rel ON persoon.id = rel.pid
                          WHERE rel.vid = 3)

Wat betekent mijn avatar?


  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
Verwijderd schreef op maandag 28 februari 2005 @ 15:33:
code:
1
2
3
4
SELECT *
FROM person
    INNER JOIN rel ON ( persoon.id = rel.pid)
WHERE rel.vid = 2

zoiets?
Nee dit werkt niet, dan valt psies het resultaat dat ik wil hebben eraf.

www.killyourdarlings.nl


  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
Dido schreef op maandag 28 februari 2005 @ 15:42:
Op voorwaarde dat subqueries geen probleem zijn, zoiets?
code:
1
2
3
4
5
6
7
8
SELECT *
  FROM persoon
  LEFT JOIN rel ON persoon.id = rel.pid
 WHERE rel.vid = 2
   AND persoon.id NOT IN (SELECT persoon.id
                          FROM persoon
                          LEFT JOIN rel ON persoon.id = rel.pid
                          WHERE rel.vid = 3)
Ik wil geen subselect gebruiken en daarnaast heb ik wel een test gedaan met een NOT statement maar het zijn duizende records en toen kwam ik uit op een zoektijd van een aantal minuuten, geen optie dus.
Toch bedankt ;)

www.killyourdarlings.nl


  • Dido
  • Registratie: Maart 2002
  • Laatst online: 09:16

Dido

heforshe

Zonder subquery wordt het lastig...

"iedereen met een fiets, die niet voorkomt in de lijst van iedereen die een auto heeft" is de eenvoudigste manier om te omschrijven wat jij wilt (en exact wat mijn query doet).

Constateren dat iemand geen auto heeft kan alleen door te kijken of er een record bestaat van die persoon met een auto, tenzij je "negatieve" vermeldingen op gaat nemen (maar dat lijkt me niet echt zinvol).

Als je performance zo slecht is, zou je kunnen overwegen e.e.a. applicatief op te lossen?

Wat betekent mijn avatar?


  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
Het moet draaien op MySql versie 3.23.49. Daarin worden nog geen sub query's ondersteund. En aplicabel oplossen? Uhhh :?
Maar volgens mij is het echt mogelijk met joins. Ik zat de denken om dezelfde table twee keer te joinen met een alias om zo te kunnen vergelijken.

www.killyourdarlings.nl


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Zoiets?
code:
1
2
3
4
5
6
7
SELECT *
FROM 
   persoon
   JOIN rel ON persoon.id = rel.pid AND rel.vid = 2
   LEFT JOIN rel rel2 ON persoon.id = rel2.pid AND rel2.vid = 3
WHERE
  rel2.pid IS NULL -- maar dan dus een rel die niet bestaat

  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
Ik heb het!
code:
1
2
3
4
SELECT  * 
FROM persoon 
LEFT  JOIN rel ON ( persoon .id = rel.pid AND rel.vid =2  )
where rel.id is null

Ik moest dus een extra 'id' field aanmaken in de relatie tabel waar ik op moest testen of die null was.
Ik kon niet op de vid of op de pid testen omdat die al in de query voorkwamen met een vergelijking!
Beetje vreemd maar het werkt wel.
Dus die subselect was toch nergens voor nodig :)

Ps. Eerst een join maken en dan kijken of die voldoet. en dan de Null eruitvissen voor de behalve-filter! Vervolgens kun je in de where statement ook nog op andere labels filteren!!

Tanks tweakers!

www.killyourdarlings.nl


  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 12-05 17:33
daankyd schreef op dinsdag 01 maart 2005 @ 09:49:
Ik heb het!
code:
1
2
3
4
SELECT  * 
FROM persoon 
LEFT  JOIN rel ON ( persoon .id = rel.pid AND rel.vid =2  )
where rel.id is null
mmm..
code:
1
2
3
SELECTEER ALLE PERSONEN, 
    JOIN DE RELATIETABEL ERTEGENAAN VOOR AL DEZE PERSOON MITS vid=2
EN GEEF ME DIE PERSONEN TERUG WAARVOOR DE JOIN NIET KON WORDEN TOEGEPAST.

Nu weet ik niet wat vid=2 is, maar ik ga ervan uit dat dat betekent: 'HEEFT FIETS'

Hoe weet je dan nu zeker dat die mensen GEEN auto hebben? Of snap ik (en meerderen hierboven) je vid=2 niet?

Je kunt natuurlijk nogmaals die relatietabel ertegenaan joinen (met een alias) met AND vid=3
en dan zeggen:
WHERE rel1.id IS NULL AND rel2.id NOT NULL

Dan wordt het dit:

code:
1
2
3
4
5
SELECT  * 
FROM persoon 
LEFT  JOIN rel as rel1 ON ( persoon .id = rel1.pid AND rel1.vid =2  )
LEFT  JOIN rel as rel2 ON ( persoon .id = rel2.pid AND rel2.vid =3  )
WHERE rel1.id IS NULL AND rel2.id NOT NULL

  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
vid=2 betekend heeft auto, dan kijk ik naar het resultaat. als heeft auto mislukt (is null) dan klopt het ;) .
ik heb nu deze code:
code:
1
2
3
4
5
6
7
SELECT  * 
FROM persoon AS p1
LEFT JOIN rel AS r1 ON ( p1.id = r1.pid AND r1.vid =2  ) // koppel met de gefilterde tabel op auto
LEFT JOIN rel AS r2 ON (p1.id=r2.pid) // koppel dit weer met die hele tabel
WHERE 
r1.id is null AND // selecteer die mislukte auto's
r2.vid=1// die dus nog wel een fiets hebben

Sja het is een beetje een byzar probleem dat heel simpel lijkt maar het viel me wel zwaar.
Lijkt me dat het een veel voorkomend probleem is. een tabel met labels en een koppeltabel. Dat je dan kan zoeken op een label en een behalve label. maarja...

www.killyourdarlings.nl


  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 12-05 17:33
Okee, je hebt die dubbele join dus al toegepast, dat bleek niet uit je voorlaatste post.
Ik vroeg het me alleen nog maar even af, want de query die daarbij stond deed volgens mij niet wat je in je topicstart omschreef! ;)

Overigens vind ik dit niet echt een bizar probleem. Komt wel vaker voor.

  • daankyd
  • Registratie: December 2002
  • Laatst online: 29-04 14:08
beetle71 schreef op dinsdag 01 maart 2005 @ 11:11:
Okee, je hebt die dubbele join dus al toegepast, dat bleek niet uit je voorlaatste post.
Ik vroeg het me alleen nog maar even af, want de query die daarbij stond deed volgens mij niet wat je in je topicstart omschreef! ;)

Overigens vind ik dit niet echt een bizar probleem. Komt wel vaker voor.
Ja, het probleem concentreerde zich om het vinden van die zonder auto gasten ;) Dus had even die fiets laten zitten. Maar nu is alles compleet.

www.killyourdarlings.nl

Pagina: 1