[MySql] Join met voorwaarden

Pagina: 1
Acties:

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10 13:03
Ik heb een ordersysteem gebouwd, resulterende in o.m. de volgende tabellen:
  • orders (ID, klantId)
  • orderregels (ID, orderId, productId)
  • klanten (ID, naam)
  • producten (ID, naam, prijs)
  • productenLabels (klantId, productId, naam)
Wat is het probleem? Producten hebben een naam, maar deze naam verschilt per klant. De tabel productenLabels geeft de naam voor een bepaald product voor een bepaalde klant. Nu wil ik in 1 query alle orderregels van een bepaalde order uit de db trekken, met de volgende output:


code:
1
[orderregelId][productId][klant-productnaam]


Mijn probleem is: dit lukt mij niet. Dit is mijn query tot zover

SQL:
1
2
3
4
SELECT DISTINCT ID, orderregelsproducten.productId, IF(productenlabels.klantId=orders.klantId, productenlabels.naam, null) AS 'klantProductNaam'
FROM orders, orderregelsproducten
LEFT JOIN productenlabels ON (productenlabels.productId = orderregelsproducten.productId) WHERE orders.ID = orderregelsproducten.orderId
ORDER BY productId


Hij lijkt het goed te doen, maar geeft voor ieder product waarvan een alternatieve naam is opgegeven in de tabel productenLabels twee resultaten:

code:
1
2
3
4
5
6
7
[orderregelId][productId][klant-productnaam]
     1            3            Appel
     1            3            NULL
     2            4            Ei
     2            4            NULL
     3            34           NULL
     4            22           NULL


Hoe kan dit?

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 01:41

MueR

Admin Devschuur® & Discord

is niet lief

Hoe het kan weet ik zo even niet, ben niet helder meer momenteel. Je kan het iig wel oplossen, door een GROUP BY productId in je query op te nemen.

Anyone who gets in between me and my morning coffee should be insecure.


  • Brainstorm
  • Registratie: November 2000
  • Laatst online: 29-11 11:17
Je gebruikt een left join, wil je niet een inner join doen?

code:
1
2
3
4
SELECT [orderregels].[ID], [orderregels[.[productId], [productentlabels].[naam]
FROM [orderregels]
INNER JOIN [productenlabels] on ([orderregels[.[productId] = [productentlabels].[productId])
WHERE [orderregels].[orderid] = 10

[ Voor 12% gewijzigd door Brainstorm op 25-04-2007 17:55 . Reden: productid en naam aan de select toegevoegd ]

Programmer's Drinking Song: 99 little bugs in the code, 99 bugs in the code, Fix one bug, compile it again, 100 little bugs in the code. (go to start if bugs>0)


  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 21-11 19:40
code:
1
2
3
4
5
SELECT orderregels.ID, orderregels.productId, productentlabels.naam
FROM orderregels 
INNER JOIN orders on (orderregels.orderId = orders.ID)
INNER JOIN productenlabels on (orderregels.productId = productentlabels.productId AND orders.klantId = productenLabels.klantId)
WHERE orderregels.orderid = 10


Je moet natuurlijk niet vergeten om je klantid op te halen en deze te gebruiken om de juiste naam op te halen.

Verder zou ik in elke tabel die ID wegslopen en hem een fatsoenlijke naam geven. De ID in orders zou ik dus OrderId noemen. Die in orderregels OrderregelsId. Enzovoorts. Dan weet je later bij het programmeren ook welke ID waarvoor staat :)

Edit:
quote: Rekcor
Hij lijkt het goed te doen, maar geeft voor ieder product waarvan een alternatieve naam is opgegeven in de tabel productenLabels twee resultaten:
Dit zal waarschijnlijk komen doordat de eerste naam die dan in de productenLabels tabel staat niet van de juiste klant is. Zo'n if statement kan je ook veel beter in een WHERE of JOIN zetten. Dan worden er alleen waardes opgehaald waar je wat mee wilt doen. En hoef je later dus niet te bekijken of de opgehaalde waardes wel hetgeen is wat je nodig hebt.

[ Voor 28% gewijzigd door DamadmOO op 25-04-2007 19:35 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Moet je niet gewoon je left-join voor de productlabels uitbreiden met een AND voor de klant.id? Dus zoiets:

SQL:
1
2
3
4
5
6
7
SELECT ID, p.productId, COALESCE(l.naam, p.naam) 
   AS productnaam -- <- daar hoeft geen ' omheen en dan bij mysql sowieso `!
FROM orders o
JOIN orderregelsproducten p ON o.ID = p.orderId
LEFT JOIN productenlabels l ON l.productId = p.productId
                                  AND l.klantid = o.klantid
ORDER BY productId


Deze constructie zal als je die geprobeerd hebt in eerste instantie niet gewerkt hebben omdat je de orders en orderregelsproducten niet aan elkaar joinde en je de productenlabels daardoor enkel aan orderregelsproducten joinde.

[ Voor 20% gewijzigd door ACM op 25-04-2007 19:59 ]