[MySQL][PHP]2 tabellen, veel op veel...

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste GoT-ers..

Ik zit met een sql probleem.
Ik heb 2 tabellen, foto en trefwoord. Die hebben een veel op veel relatie dus heb ik ook een koppel tabel foto_trefwoord. Tot nu toe is het nog duidelijk.

Nu probeerde ik alle foto's te krijgen die zowel een koppeling met trefwoord id 5 als id 7 hebben.
Niet zo moeilijk dacht ik.

Dit viel zwaar tegen. Met alle queries die ik geprobeert heb krijg ik of te veel of niks.
Bij te veel results was het duidelijk een 'OR' dus alle fotos die of 5, of 7 gekoppeld hebben.

Ik heb MySQL versie < 4.0 dus subqueries en unions zijn niet mogelijk.
En daarbij heb ik ook nog het probleem dat het 1 querie moet zijn. dus ik kan niet alles van 5 eerst selecteren en dan met php de boel verder filteren.

dit is de querie die er het dichtst bij kwam.

code:
1
2
3
4
5
SELECT foto. * 
FROM foto_trefwoord
INNER  JOIN foto ON foto_trefwoord.fotoId = foto.fotoId
INNER  JOIN trefwoord ON trefwoord.trefwoordId = foto_trefwoord.trefwoordId
WHERE trefwoord.trefwoordId = 5 OR trefwoord.trefwoordId = 7


Als ik de eerste Inner join vervang door een left heeft het geen effect.
De reden waarom ik in de 'from' uit de koppel tabel selecteer, is omdat anders de inner join een error geeft. Luisterd nauw naar volgorde meen ik gelezen te hebben op mysql.com
Ik hoop dat ik alles een beetje normaal heb uitgelegd. :)

Weet iemand hoe het wel moet of kan het gewoon helemaal niet.

thnx Commodus2

Acties:
  • 0 Henk 'm!

  • raoulduke
  • Registratie: Oktober 2003
  • Niet online

raoulduke

Get in!

Vervang OR door AND?

Edit:
Dit was te simpel.

[ Voor 43% gewijzigd door raoulduke op 17-11-2003 22:20 ]

Remember, if you have any trouble you can always send a telegram to the Right People.


Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 12:54
En jij hebt ook al gebruik gemaakt van "AND" in plaats van die "OR" in de WHERE clause?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
als ik dat doe, krijg ik geen results terug (dacht je dat ik dat nog niet geprobeerd had :) )

Dit komt omdat de where clasue voor 1 row geldt en het gaat bij mij om meerdere koppelingen.

een koppeling ziet er zo uit:
code:
1
2
3
fotoid     trefwoordId
4            7
4            5

Als ik dus AND neer zou zetten is het altijd false want dat is nooit waar voor 1 row


volgens mij...

Ik wil dus (als dit mijn hele database was) foto 4 terug krijgen, omdat deze zowel 5 als 7 gekoppeld heeft.

[ Voor 14% gewijzigd door Verwijderd op 17-11-2003 22:18 ]


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Ik snap niet waarom je dan drie tabellen gaat joinen, met twee heb je toch genoeg dan??
code:
1
2
3
SELECT foto.* FROM foto_trefwoord, foto WHERE
  foto_trefwoord.fotoId=foto.fotoId AND
  foto_trefwoord.trefwoordId IN (5,7)


edit:

Ow ja, en als je wilt voorkomen dat je dezelfde foto 2 keer krijgt dan kun je een SELECT DISTINCT doen

[ Voor 22% gewijzigd door beetle71 op 17-11-2003 22:38 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Die querie heb ik ook geprobeert.
Dit is weer een OR en ik moet AND hebben
de in() is echt alleen OR

Ik zou het niet vragen hier als ik er niet uitkwam en al verschillende dingen heb geprobeert.

Acties:
  • 0 Henk 'm!

Verwijderd

doe eens "GROUP BY foto.fotoId" erachter plakken...

Acties:
  • 0 Henk 'm!

  • Apollo_Futurae
  • Registratie: November 2000
  • Niet online
Dit werkt in ieder geval:

SQL:
1
2
3
4
5
6
7
SELECT foto.id
FROM foto
  INNER JOIN foto_trefwoord ON (foto.id = foto_trefwoord.foto)
  INNER JOIN trefwoord ON (foto_trefwoord.trefwoord = trefwoord.id)
WHERE trefwoord.id IN (5,7)
GROUP BY foto.id
HAVING COUNT(trefwoord.id) = 2


Erg mooi vind ik het niet, maar ja.
De 2 in de HAVING clause moet je in het algemeen vervangen door het aantal elementen in de IN expressie.
Let er verder op dat de combinatie (foto,trefwoord) in de koppeltabel uniek moet zijn.

[ Voor 1% gewijzigd door Apollo_Futurae op 17-11-2003 23:07 . Reden: layout gered ]

Pas de replâtrage, la structure est pourrie.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
:( group by erbij zetten geeft hetzelfde resultaat


maar ik heb denk ik de oplossing. Het is erg lame maar goed
Deze Querie moet ik dus dynamisch gaan opbouwen aan de hand van het aantal trefwoorden die ik zoek
code:
1
2
3
4
SELECT foto. * 
FROM foto_trefwoord foto_trefwoord1, foto_trefwoord foto_trefwoord2, foto
WHERE foto_trefwoord1.fotoId = foto.fotoId AND foto_trefwoord1.trefwoordId
IN ( 5  )  AND foto.fotoId = foto_trefwoord2.fotoId AND foto_trefwoord2.trefwoordId IN ( 7  )

het is volgens mij de meest brakke query die ik bedacht heb.. maar het is tot nu toe de enige die waarschijnlijk werkt. Een dubbele join met een join table...
en dit dus voor iedere trefwoord een join erbij

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Apollo_Futurae schreef op 17 november 2003 @ 23:07:
Dit werkt in ieder geval:

SQL:
1
2
3
4
5
6
7
SELECT foto.id
FROM foto
  INNER JOIN foto_trefwoord ON (foto.id = foto_trefwoord.foto)
  INNER JOIN trefwoord ON (foto_trefwoord.trefwoord = trefwoord.id)
WHERE trefwoord.id IN (5,7)
GROUP BY foto.id
HAVING COUNT(trefwoord.id) = 2


Erg mooi vind ik het niet, maar ja.
De 2 in de HAVING clause moet je in het algemeen vervangen door het aantal elementen in de IN expressie.
Let er verder op dat de combinatie (foto,trefwoord) in de koppeltabel uniek moet zijn.
Cool die werkt idd!.thnx!
En ik denk stukke sneller dan de mijne...

[ Voor 4% gewijzigd door Verwijderd op 17-11-2003 23:17 ]


Acties:
  • 0 Henk 'm!

  • Bubbaman
  • Registratie: Juli 2003
  • Laatst online: 20-03-2022
Tja, dat soort problemen had ik ook....
Simpele oplossing: zet de JOIN ON tussen haakjes......

Voorbeeld (in PHP4):
$sql = mysql_query("SELECT * FROM table1 LEFT JOIN table2 ON (table1.field1 = table2.field1 OR table1.field1 = table2.field2)",$db);

Dit werkt prima bij mij.

Rob

[ Voor 10% gewijzigd door Bubbaman op 17-11-2003 23:19 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bubbaman schreef op 17 november 2003 @ 23:17:
Tja, dat soort problemen had ik ook....
Simpele oplossing: zet de JOIN ON tussen haakjes......

Voorbeeld:
$sql = mysql_query("SELECT * FROM table1 LEFT JOIN table2 ON (table1.field1 = table2.field1 OR table1.field1 = table2.field2)",$db);

Dit werkt prima bij mij.

Rob
Dit meen je niet... dit werkt en ik zit gewoon weer veel te omsclachtig te doen met dubbele koppeltabel joins :)

dit HAVING werkt ook goed btw.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thnx GoT-ers.

het werkt allemaal als een zonnetje.
Alleen vraag ik me af of het de snelste manier is.

Anders maar de boel overhalen om naar mysql 4.1 te gaan. heb je subqueries

maar thnx in ieder geval :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op 17 november 2003 @ 23:02:
doe eens "GROUP BY foto.fotoId" erachter plakken...
Waarom zou je hier een GROUP BY nodig hebben ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • bigtree
  • Registratie: Oktober 2000
  • Laatst online: 16-08 17:16
Het kan ook zonder GROUP BY:
code:
1
2
3
4
SELECT foto.id
FROM foto
INNER JOIN foto_trefwoord AS t1 ON ( foto.id = t1.foto AND t1.trefwoord = 5 ) 
INNER JOIN foto_trefwoord AS t2 ON ( foto.id = t2.foto AND t2.trefwoord = 7 )
Ik denk dat dit sneller is dan de GROUP BY-methode, dus benchmark de twee opties die je hebt om te kijken welke methode het snelst is.

Lekker woordenboek, als je niet eens weet dat vandalen met een 'n' is.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
bigtree schreef op 18 november 2003 @ 08:53:
Het kan ook zonder GROUP BY:
code:
1
2
3
4
SELECT foto.id
FROM foto
INNER JOIN foto_trefwoord AS t1 ON ( foto.id = t1.foto AND t1.trefwoord = 5 ) 
INNER JOIN foto_trefwoord AS t2 ON ( foto.id = t2.foto AND t2.trefwoord = 7 )
Ik denk dat dit sneller is dan de GROUP BY-methode, dus benchmark de twee opties die je hebt om te kijken welke methode het snelst is.
Tuurlijk kan het zonder group by. Daarom vraag ik ook waarom die GROUP BY voorgesteld wordt.
Een group by heb je helemaal niet nodig als je niet met aggregated fields werkt.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dus de 'group by and having' querie is niet zo snel?

Ik zal zeker de query uitproberen zonder de group by
thnx

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op 18 november 2003 @ 10:59:
Dus de 'group by and having' querie is niet zo snel?
GROUP BY en HAVING heb je enkel en alleen nodig als je gebruik maakt van aggregated functions zoals sum, count, avg, ....

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ok dan... weer wat geleerd. thnx

code:
1
2
3
4
SELECT foto.id
FROM foto
INNER JOIN foto_trefwoord AS t1 ON ( foto.id = t1.foto AND t1.trefwoord = 5 ) 
INNER JOIN foto_trefwoord AS t2 ON ( foto.id = t2.foto AND t2.trefwoord = 7 )

werkt idd sneller naar mate je meer koppelingen gaat krijgen
dus thnx again

Acties:
  • 0 Henk 'm!

  • jaydeed1
  • Registratie: December 2000
  • Laatst online: 11-09 17:37
Ik denk ook or naar and

[ Voor 70% gewijzigd door jaydeed1 op 04-02-2007 23:28 ]

Pagina: 1