Toon posts:

[MYSQL] zelfde tabel, meerdere velden met JOIN

Pagina: 1
Acties:
  • 225 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Beste mensen,

Hierbij een vraagstuk over een JOIN tussen twee tabellen. Met de search heb ik niet veel kunnen vinden, omdat ik niet weet welke zoekwoorden ik met betrekking tot deze kwestie het beste kan gebruiken.

De linkertabel (GEBOUW_OBJECT) bevat woningen. De rechtertabel (FOTO) bevat tot maximaal 3 foto's van de woning. Door dit vaste aantal foto's heb ik in de tabel GEBOUW_OBJECT drie kolommen gemaakt, FOTO_id, FOTO2_id en FOTO3_id.

Een (logische) optie zou zijn om in de tabel FOTO een vreemde sleutel GEBOUW_OBJECT_id op te nemen. Dit is echter een hele grote klus, aangezien het een bestaande database betreft die in een behoorlijk grote site is geworteld. Bovendien zou je dan (volgens mij) niet meer weten welke foto welke is (met andere woorden, welke foto zou foto 1 zijn, welke foto zou foto 2 zijn, enz).

Daarom kies ik voor een minder logisch alternatief: met behulp van een JOIN alledrie de url's uit de tabel FOTO verkrijgen. Een query met meerdere JOINs naar dezelfde tabel geeft so wie so al een foutmelding, en de volgende query werkt (zoals verwacht) ook niet:

code:
1
2
3
4
5
SELECT FOTO.url, FOTO.url AS url2, FOTO.url AS url3
FROM GEBOUW_OBJECT
LEFT JOIN FOTO ON GEBOUW_OBJECT.FOTO_id = FOTO.id
OR GEBOUW_OBJECT.FOTO2_id = FOTO.id
OR GEBOUW_OBJECT.FOTO3_id = FOTO.id


Bij bovenstaande query krijg ik als url, url2 en url3 dezelfde waarde terug (die van url). Had ook niet anders verwacht hoor, maar goed.

Iemand een suggestie hoe ik bovenstaande kwestie werkend kan krijgen? Bij voorbaat dank :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:31
Je moet joinen met een AND operator ipv met een OR.
Je zult voor ieder foto_id veld, een andere tabel moeten nemen, en je zult die dus ook moeten OUTER joinen:

code:
1
2
3
4
5
SELECT foto.url
FROM gebouw_object
LEFT JOIN foto foto1 ON gebouw_object.foto_id = foto1.id
LEFT JOIN foto foto2 ON gebouw_object.foto2_id = foto2.id
....


Dit alles buiten beschouwing gelaten: Ik vind jouw oplossing geen mooie oplossing. Je had beter gekozen voor het creeëren van een extra tabel waarmee je dus kon aangeven welke foto er tot welk gebouw behoort (als je er van uitgaat dat eenzelfde foto tot meerdere gebouwen kan behoren).
Als een foto niet tot meerdere gebouwen kan behoren, had je beter het gebouw_id in de tabel 'FOTO' opgenomen als foreign key. Op die manier is het geheel veel beter beheersbaar (queries schrijven gaat makkelijker) en uitbreidbaar: stel dat je binnen 2 maand beslist dat er ook wel eens 5 foto's van een gebouw moeten bijgehouden worden, dan mag je je DB-model gaan aanpassen met jouw oplossing.

[ Voor 16% gewijzigd door whoami op 02-01-2004 21:05 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik ben het absoluut met je eens, een mooie oplossing is het niet. In de huidige situatie kan er maar één foto bij een woning geplaatst worden. Met het oog op schaalbaarheid (meerdere foto's bij een woning) is het databaseontwerp niet echt goed te noemen. Het is natuurlijk veel logischer dat er meer foto's bij een woning geplaatst kunnen worden, dan andersom.

Feit blijft dat ik het hiermee moet doen, tenzij ik tientallen query's en stukken PHP aan pas.

Wat ik uit je reply begrijp, is dat het niet mogelijk is om in één query die drie velden uit dezelfde kolom in de tabel FOTO te verkrijgen. Correct?

Een andere optie, zonder het databaseontwerp helemaal om te hoeven gooien, is het maken van verschillende query's...

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:31
Verwijderd schreef op 02 januari 2004 @ 22:38:
Wat ik uit je reply begrijp, is dat het niet mogelijk is om in één query die drie velden uit dezelfde kolom in de tabel FOTO te verkrijgen. Correct?
Lees het eerste gedeelte van m'n reply nog eens goed. ;)

https://fgheysels.github.io/


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Sowieso moet je de joins omdraaien:
select ... from gebouw g, foto f1, foto f2, foto f3 where g.foto1 = f1 and g.foto2 = f2 ...

of dat weer in een drietal left join verwerken

[ Voor 17% gewijzigd door ACM op 02-01-2004 22:53 ]


Verwijderd

Topicstarter
whoami: Ik zie niet helemaal wat je bedoelt. Als ik AND gebruik (zie onder), dan krijg ik helemaal geen resultaten, omdat hetzelfde veld met verschillende waarden wordt vergeleken. Het is ook vast niet wat je bedoelt, maar ik snap niet wat je precies uit probeert te leggen...

code:
1
2
3
4
5
SELECT FOTO.url, FOTO.url AS url2, FOTO.url AS url3
FROM GEBOUW_OBJECT
LEFT JOIN FOTO ON GEBOUW_OBJECT.FOTO_id = FOTO.id
AND GEBOUW_OBJECT.FOTO2_id = FOTO.id
AND GEBOUW_OBJECT.FOTO3_id = FOTO.id


ACM: ook jouw query snap ik niet helemaal... :X Ben nog niet zo'n SQL held. Wat bedoel je met de JOINs omdraaien? In plaats van een LEFT een RIGHT gebruiken?

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:31
Je moet die query die ik in m'n eerste post gezet heb toch eens beter bekijken. Ik join niet met 1, maar met 3 tabellen.

https://fgheysels.github.io/


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

ACM: ook jouw query snap ik niet helemaal... :X Ben nog niet zo'n SQL held. Wat bedoel je met de JOINs omdraaien? In plaats van een LEFT een RIGHT gebruiken?
Als je dan de voorbeeld-queries van mij en whoami met die van jezelf vergelijkt?
En es goedkijkt naar welke tabellen daar gebruikt worden en hoe die gebruikt worden?

Jij joint de (2) foto-tabel aan de (1) gebouw-tabel, meer niet. Wat doen wij? Kijk es goed? Hoeveel getalletjes moet je bij onze queries gebruiken?

Verwijderd

Topicstarter
Aah kijk... nu heb ik 'm! Sorry.

Wat jullie doen, is dus drie aliassen (tows3r-taal?) maken voor de FOTO tabel (foto1, foto2, foto3). Die syntax kende ik nog niet, vandaar dat ik het niet helemaal begreep. Door het maken van aliassen maak je dus in principe drie aparte tabellen, die je wél alledrie kan JOINen.

Ik heb het op de volgende manier opgelost:

code:
1
2
3
4
5
SELECT foto1.url, foto2.url, foto3.url
FROM GEBOUW_OBJECT
LEFT JOIN FOTO foto1 ON GEBOUW_OBJECT.FOTO_id = foto1.id
LEFT JOIN FOTO foto2 ON GEBOUW_OBJECT.FOTO2_id = foto2.id
LEFT JOIN FOTO foto3 ON GEBOUW_OBJECT.FOTO3_id = foto3.id


Wederom bedankt voor de leerzame reply's!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:31
Toch blijf ik erbij dat je je datamodel beter veranderd.

Met de query die je nu hebt , werkt het wel, maar echt performant kan je het niet noemen. (Een OUTER JOIN is niet echt goed voor de performantie, en nu moet je er dus 3 doen).

https://fgheysels.github.io/


Verwijderd

Topicstarter
Geef ik je helemaal gelijk in, een mooie oplossing is het niet. Als ik de database en de site from scratch aan het opbouwen was, had ik het zeker zo gedaan. Het probleem is gewoon dat dit ontwerp helemaal vastgeroest zit in zowel de site als in de admin. Op zich zou het veranderen van het databaseontwerp en het verplaatsen van bepaalde gegevens in de DB (alle woningen aan foto's koppelen, ipv andersom, zoals het nu is) niet zo'n probleem zijn, maar alle PHP er om heen wel.

Gelukkig hoeft deze query niet erg vaak uitgevoerd te worden, echte problemen levert het dus niet op. Ik vind dat in dit geval de performance niet opweegt tegenover al het werk wat ik er voor zou moeten doen.

In ieder geval een wijze les voor de volgende klant ;) Nogmaals dank!
Pagina: 1