Join haalt data uit andere tabel niet juist op
Dit werkt wel:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT m.name, m.surname, n.id, n.title AS title, n.message_short, n.message, n.date_posted, n.date_editted, n.active
FROM nieuws n
INNER JOIN members m ON n.author = m.id
WHERE n.active = '1'
AND n.deleted='0'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
FROM nieuws n
INNER JOIN members m ON n.author = m.id
WHERE n.active = '1'
AND n.deleted='0'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
Maar nu wil ik dus een speciaal thumbnail-plaatje meegeven die gekoppeld is aan het bericht.
Dit is de tabel uploads-items, hieraan kan ik meerdere foto's aan een item (nieuwsbericht, review, agenda; wordt bepaald met een integer in UploadtypeID waar 7 in dit geval voor nieuwsberichten staan) koppelen. Die met Featured is de thumbnail die hij moet pakken, per KindID en Uploadtype_ID kan er normaal gezien maar eentje bestaan.
Dit is de tabel uploads, en staan alle uploads in.
Nu geeft deze query alleen een enkel record i.p.v. de laatste vier?
De bedoeling is dus dat hij in de upload_items tabel kijkt of het KindID bestaat, en anders moet filename gewoon leeg zijn, want een thumbnail is niet verplicht.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
SELECT m.name, m.surname, n.id, n.title AS title, n.message_short, n.message, n.date_posted, n.date_editted, n.active, n.author,up.filename
FROM nieuws n
INNER JOIN members m ON n.author = m.id
LEFT JOIN uploads_items ui ON ui.KindID = n.id
LEFT JOIN uploads up ON up.ID = ui.UploadID
WHERE n.active = '1'
AND ui.Featured = '1'
AND n.deleted='0'
AND Uploadtype_ID = '7'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
FROM nieuws n
INNER JOIN members m ON n.author = m.id
LEFT JOIN uploads_items ui ON ui.KindID = n.id
LEFT JOIN uploads up ON up.ID = ui.UploadID
WHERE n.active = '1'
AND ui.Featured = '1'
AND n.deleted='0'
AND Uploadtype_ID = '7'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
Hoe kan dat? Ik hoop dat het verhaal een beetje duidelijk is.
Gewijzigd op 26/07/2017 21:27:20 door - Ariën -
SELECT m.name, m.surname, n.id, n.title AS title, n.message_short, n.message, n.date_posted, n.date_editted, n.active,
(SELECT up.filename FROM
uploads up INNER JOIN uploads_items ui ON
up.ID = ui.UploadID
WHERE ui.KindID = n.id
AND ui.Featured = '1'
AND Uploadtype_ID = '7' LIMIT 1) AS filename
FROM nieuws n
INNER JOIN members m ON n.author = m.id
WHERE n.active = '1'
AND n.deleted='0'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
Een LEFT JOIN in combinatie met WHERE is ook wat lastig, omdat je in het geval van een LEFT JOIN ook NULL wil toestaan. Hier zul je dan in de WHERE mee rekening moeten houden, of je conditie verplaatsen naar de JOIN.
Ik had niet verwacht dat er een subselect met die JOIN nodig voor zou zijn.
Vergeleken met zonder subselect heeft het wel als voordeel dat er meerdere waardes van een ID en KindID een 1 kunnen hebben (wat normaal nooit voorkomt), terwijl dat geen dubbele records zal tonen. Hij pakt zelfs netjes de eerste in de rij. Best robuust zelfs!
Gewijzigd op 26/07/2017 23:00:08 door - Ariën -
Zolang je daar geen condities voor geeft zou je dat heel erg niet moeten willen, al is het alleen maar omdat "eerste" een arbitrair iets is.
Voor de performance zou je dat soort zaken wel een beetje moeten voorkomen, omdat nu per saldo per tuple dezelfde query nog een keer gedraaid wordt. Mogelijk werkt zoiets ook (ik wist niet zeker uit welke tabel UploadTypeID moest komen):
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT m.name, m.surname, n.id, n.title AS title, n.message_short, n.message, n.date_posted, n.date_editted, n.active, n.author,up.filename
FROM nieuws n
INNER JOIN members m ON n.author = m.id
LEFT JOIN uploads_items ui ON ui.KindID = n.id AND ui.Featured = '1' AND ui.Uploadtype_ID = '7'
LEFT JOIN uploads up ON up.ID = ui.UploadID
WHERE n.active = '1'
AND n.deleted='0'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
FROM nieuws n
INNER JOIN members m ON n.author = m.id
LEFT JOIN uploads_items ui ON ui.KindID = n.id AND ui.Featured = '1' AND ui.Uploadtype_ID = '7'
LEFT JOIN uploads up ON up.ID = ui.UploadID
WHERE n.active = '1'
AND n.deleted='0'
AND n.date_posted <= NOW()
ORDER BY n.date_posted DESC
LIMIT 4
Gewijzigd op 26/07/2017 23:56:57 door Ben van Velzen
Ik hoef immers toch niet aan te geven wat voor type (nieuws,reviews,event etc..) het is, en of er een gallery gebruikt hoeft te worden. Wel moet dit veld gespecificeerd worden omdat een KindID niet geheel uniek is. Een nieuwsartikel met het ID 43 kan bestaan, maar ook een review of event kan eht ID 43 hebben, en daar is onderscheid voor nodig.
Het is netter geweest om dit in een enkele tabel op te slaan naturlijk, maar dat is niet zo makkelijk gedaan, omdat elke tabel weer een hoop eigen metadata heeft.
Ik zal jouw query ook eens binnenkort proberen, en kijken welke het snelste is ;-)
Gewijzigd op 27/07/2017 00:02:53 door - Ariën -
Gewijzigd op 27/07/2017 00:04:10 door Ben van Velzen