Query join/union hulp
Ik kom er echt niet uit, maar komt omdat ik het weer beetje heb aangepast, oke de situatie is alsvolgt.
table: items (id, tokenId, postedOn)
table: token (id, name)
table: itemsKeywords(id, name)
table: users (id, name)
table: usersFriends(id, userId, friendUserId)
op de hoofdpagina moet je een overzicht krijgen met alle items gesorteerd op postedOn (meest recent dus), het systeem werkt nu zo:
gebruiker komt op pagina, al de vrienden van de gebruiker worden opgehaald (dus SELECT `friendUserId` FROM `usersFriends` WHERE `userId` = ?) vervolgens:
foreach($friends as &$f){
// query 1. haal alle items op
// query 2. haal de keywords op
}
maar het moet allemaal veel sneller en in een query kunnen, ook is het nu dus ONMOGELIJK om de meest recente op te halen (order by postedOn) omdat je dus eerst al je vrienden op gaat halen.
Wie kan mij helpen, pm evt.
Gewijzigd op 24/11/2011 21:00:06 door Mike V
Alvast bedankt.
Wat je in elk geval kan doen is een union gebruiken.
Ja ik weet dat het met een union kan maar hoe zou ik dat dan moeten doen? Er is maar 1 tag mogelijk, een item heeft dus een tagid, dus 1 tag is mogelijk daarin tegen kan een item dus meerder keywords hebben en daar loopt de query op vast.
Stap 2: zorg dat de selects van hierboven een gelijk aantal velden oplevert, voeg extra velden toe (gewoon via SELECT null) als het aantal niet gelijk is
Stap 3: voeg die samen door ze tussen haakjes te zetten en er UNION tussen te zetten.
Klaar is klara. Let wel, de namen van de uiteindelijke velden worden de namen die je in de eerste query hebt gedefinieerd. De tweede kan geen nieuwe veldnamen opleveren.
`item`.`id`,
`item`.`name`,
`item`.`tagId`,
`tags`.`name`,
`keywords`.`name`,
`keywords`.`id`
FROM `items`
INNER JOIN `tags` ON `tags`.`id` = `item`.`tagId`
INNER JOIN `keywords` ON `keywords`.`itemId` = `item`.`id`
WHERE `item`.`id` = ?
Verder dan dat kom ik echt niet, ik snap niet wat je bedoelt met select null enzo. Igg al bedankt voor de reacties :)
query 1:
SELECT
`item`.`id`,
`item`.`name`,
`item`.`tagId`,
`tags`.`name`
FROM `items`
INNER JOIN `tags` ON `tags`.`id` = `item`.`tagId`
query 2:
SELECT
`item`.`id`,
`item`.`name`,
`item`.`tagId`,
`keywords`.`name`,
`keywords`.`id`
FROM `items`
INNER JOIN `keywords` ON `keywords`.`itemId` = `item`.`id`
Ik heb de where even weggelaten, maar heb je wel nodig als je het standalone wilt doen. Ik plaats unions meestal in een view waardoor de where pas later aan bod komt.
Maar zoals je nu ziet, heeft query1 maar 4 velden, query2 heeft er 5. Dat matched niet, dus voeg een null veld toe:
SELECT
`item`.`id`,
`item`.`name`,
`item`.`tagId`,
`tags`.`name`,
NULL
FROM `items`
INNER JOIN `tags` ON `tags`.`id` = `item`.`tagId`
Probeer er nu een union van te maken.
Beter om een LEFT of RIGHT JOIN te gebruiken
In dit geval ben het enigszins met je eens, maar indien er niet een tag, maar meerdere per item kunnen aangemaakt is een join absoluut niet het juiste antwoord. Stel je eens voor een item met 4 tags en 20 keywords..... ga jij al die rijen uitpluizen?
Ik weet niet precies wat er nog meer bij die keywords en tags komen maar misschien dat je ook wel wat kan met group_concat()
Ik kom er echt niet uit, maar komt omdat ik het weer beetje heb aangepast, oke de situatie is alsvolgt.
table: items (id, tokenId, postedOn)
table: token (id, name)
table: itemsKeywords(id, name)
table: users (id, name)
table: usersFriends(id, userId, friendUserId)
op de hoofdpagina moet je een overzicht krijgen met alle items gesorteerd op postedOn (meest recent dus), het systeem werkt nu zo:
gebruiker komt op pagina, al de vrienden van de gebruiker worden opgehaald (dus SELECT `friendUserId` FROM `usersFriends` WHERE `userId` = ?) vervolgens:
foreach($friends as &$f){
// query 1. haal alle items op
// query 2. haal de keywords op
}
maar het moet allemaal veel sneller en in een query kunnen, ook is het nu dus ONMOGELIJK om de meest recente op te halen (order by postedOn) omdat je dus eerst al je vrienden op gaat halen.
Wie kan mij helpen, pm evt.