Lastige query over drie tabellen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: « vorige 1 2

Joren de Wit

Joren de Wit

10/06/2009 17:55:00
Quote Anchor link
Dat die GROUP BY niet in de hoofdquery thuis hoort ben ik helemaal met Noppes eens. Die heb ik in eerste instantie over het hoofd gezien, maar als je er even over nadenkt klopt het inderdaad niet. Waarom zou je immers in de hoofdquery moeten groeperen?

Noppes:
En joinen in de select niet echt aan te bevelen....
Wat bedoel je daarmee?
 
PHP hulp

PHP hulp

01/11/2024 01:01:45
 
Noppes

Noppes

10/06/2009 22:48:00
Quote Anchor link
Dat als je subqueries maakt in het select gedeelte dat je die onafhankelijk moet maken.
 
Roberto Beer

Roberto Beer

11/06/2009 14:17:00
Quote Anchor link
Als ik een overzicht wil hebben van alle orders, dan is het toch logisch dat ik groepeer op orders.id?
 
Roberto Beer

Roberto Beer

11/06/2009 14:35:00
Quote Anchor link
Ik heb een afbeelding ge-upload zoals de output nu is (en die goed werkt)

http://efloria.nl/orders_overzicht.gif

Misschien verduidelijkt het de boel een beetje, maar volgens mij begrijpen jullie me al erg goed. Als de query die ik gebruik niet goed is, wat zou dan wel een goede query zijn om deze data terug te krijgen?

Gelieve Niet Bumpen::
Twee of meer keer achter elkaar in een topic posten heet bumpen. Bumpen is pas na 24 uur toegestaan en kan een reden zijn voor de admins en moderators om een topic te sluiten. Gebruik indien nodig de Afbeelding knop om je tekst aan te passen.

SanThe.
Gewijzigd op 01/01/1970 01:00:00 door Roberto Beer
 
Joren de Wit

Joren de Wit

11/06/2009 14:36:00
Quote Anchor link
Nee, dat is niet logisch. In je hoofdquery staat namelijk nergens een aggregate functie die een GROUP BY vereist.
 
Roberto Beer

Roberto Beer

11/06/2009 17:57:00
Quote Anchor link
Beste mensen,

Ik kwam erachter dat de subqueries binnen mijn query niet nodig zijn.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
SELECT orders.id, date_format(orders.datum, '%d-%m-%Y - %H:%i') AS geplaatst, orders.status, CONCAT(klanten.achternaam, ', ', klanten.voornaam) as naam, SUM(orderregels.aantal * orderregels.prijs) AS order_totaal, SUM(orderregels.aantal) AS aantal_totaal

FROM orders, klanten, orderregels, producten

WHERE orderregels.orders_id = orders.id
                AND orderregels.producten_id = producten.id
                AND orders.klanten_id = klanten.id

GROUP BY orders.id

ORDER BY orders.id DESC;


Doet precies hetzelfde. Is ie nu dan misschien goed?


----------- update:

Ik heb me na jullie kritiek eens verder verdiept in de Inner Join, de GROUP BY methode en waarom je aggregate functies moet gebruiken.

Als ik het samen mag vatten is dit de kwestie:

Je kunt alles zonder problemen uit de tabel orders halen, omdat je daarop groepeert. Maar het probleem is hoe die dan met de gegevens uit de andere tabellen moet omgaan, omdat deze min of meer 'in elkaar zijn geperst'. Dat is wat ik nu begrijp :)

Ik zie in het SELECT-gedeelte van mijn query...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
SELECT orders.id, date_format(orders.datum, '%d-%m-%Y - %H:%i') AS geplaatst,
orders.status, CONCAT(klanten.achternaam, ', ', klanten.voornaam) as naam,
 SUM(orderregels.aantal * orderregels.prijs) AS order_totaal,
SUM(orderregels.aantal) AS aantal_totaal


... dat ik dat met de velden die ik ophaal uit ORDERREGELS ook doe :) Geen probleem daar, lijkt me. Wat ik denk waar de verwarring in zit is dat ik niet heb uitgelegd dat in mijn gebouwde systeem een klant niet meer dan 1 order kan hebben.

Dit komt omdat gebruikers zich niet kunnen registeren. "Waarom laat je die tabel KLANTEN dan niet gewoon weg en zet je naam, adres, postcode et cetera niet in ORDERS?", hoor ik jullie vragen.

Welnu, ik heb dit gedaan met het oog op de toekomst. Mocht ik ooit nog een account-functie willen maken voor de gebruikers, dan is de tabellen-structuur in ieder geval goed (Ik weet ook dat, mocht ik zo'n functie gaan maken, dat de query alsnog aangepast moet worden).

Maar voor nu is de relatie KLANTEN - ORDERS 1 op 1. Dan hoeft er op de data uit de tabel KLANTEN toch geen aggregate functie worden toegepast? (omdat de data uit KLANTEN niet 'in elkaar' wordt 'geperst')

Ik ben benieuwd naar jullie reactie. Ik heb in ieder geval het gevoel dat ik het begin te begrijpen ;)
Gewijzigd op 01/01/1970 01:00:00 door Roberto Beer
 
Noppes

Noppes

13/06/2009 10:24:00
Quote Anchor link
Laat ik dan maar afsluiten met:
http://www.w3schools.com/sql/sql_groupby.asp

En gaat op internet opzoek naar hoe je op correcte wijze met sub queries moet omgaan.
 
Joren de Wit

Joren de Wit

13/06/2009 11:54:00
Quote Anchor link
@Roberto: nee, die queries die je nu hebt zijn NIET correct. Lees onderstaande tutorial nog maar eens goed door en zorg dat je MySQL goed instelt.

Het juiste gebruik van GROUP BY

En de query die je kunt gebruiken om MySQL in een strictere mode te zetten vind je hier.
 
Roberto Beer

Roberto Beer

14/06/2009 15:08:00
Quote Anchor link
Blanche, je bedoelt GROUP BY? In strict modus moet je dus groeperen op ieder kolom waarop geen Aggragatie is toegepast...

Wat ik niet helemaal snap, want als ik op ID groepeer, wat een unieke waarde heeft, waarom zou je dan nog op andere velden moeten groeperen?

Maarja, als ik dat toepas, is 'ie dan foutloos ;)?

Je schrijft heldere tutorials trouwens. Petje af.
 
Joren de Wit

Joren de Wit

14/06/2009 15:26:00
Quote Anchor link
Roberto schreef op 14.06.2009 15:08:
Wat ik niet helemaal snap, want als ik op ID groepeer, wat een unieke waarde heeft, waarom zou je dan nog op andere velden moeten groeperen?
De kolom orders.id zal in de orders tabel best uniek zijn en als je alleen velden uit die tabel selecteert zal er inderdaad niet veel aan de uitkomst veranderen. Maar dat neemt niet weg dat je niet op die kolommen moet groeperen, dat is namelijk de standaard en je voorkomt ermee dat er later bugs in je query sluipen.

Een ander verhaal is het als je ook kolommen uit andere tabellen selecteert. Dan hoeft orders.id niet per se meer unieke records op te leveren aangezien er bijvoorbeeld meerdere orderregels per order zijn.

Kortom, onthoud de vuistregel dat je altijd groepeert op alle kolommen in de SELECT waarop geen aggregatie is toegepast. Dan zit je altijd goed. (Andere databases dan MySQL dwingen dit trouwens standaard af).
 
Roberto Beer

Roberto Beer

14/06/2009 21:39:00
Quote Anchor link
Ik snap 't.

Wat is de beste manier om klanten.naam erbij op te halen? Een order heeft altijd een klant.

Ik heb nu:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
SELECT orders.id, date_format(orders.datum, '%d-%m-%Y - %H:%i') AS geplaatst,
orders.status, CONCAT(klanten.achternaam, ', ', klanten.voornaam) as naam,
 SUM(orderregels.aantal * orderregels.prijs) AS order_totaal,
SUM(orderregels.aantal) AS aantal_totaal


Waarin ik aggregatie toepas op velden uit ORDERREGELS. Alleen naam haal ik 'kaal' op, daar groepeer ik dan ook mede op.

Ik ben benieuwd hoe MySQL die tabel dan ophaalt.

Stel een order bestaat 3 orderregels, en ik zou niet groeperen.

Dan krijg ik bijvoorbeeld 3 rijen:

order_id klant_naam product id aantal
1 robbert 2 10
1 robbert 5 8
1 robbert 6 3

Dan zou ik denk ik iets als dit krijgen.

Hoe moet ik omgaan met klant_naam, het is namelijk een veld die niet uit ORDERS komt, maar uit KLANTEN. Moet ik deze aggregeren? Want er zal elke keer hetzelfde uitkomen.
 
Joren de Wit

Joren de Wit

14/06/2009 22:50:00
Quote Anchor link
Als je de orderregels apart wilt ophalen, zul je dus niet moeten gaan groeperen. In dat geval moet je er vrede mee nemen dat je in elk record ook de klantnaam ophaalt, of je moet verschillende queries willen gebruiken.

Groeperen doe je alleen als je eigenschappen van een groep wilt bepalen. Dus bijvoorbeeld aantal records in een groep, totalen van een bepaalde groep, etc.
 
Roberto Beer

Roberto Beer

15/06/2009 16:29:00
Quote Anchor link
Nee, ik wil de orderregels niet apart ophalen, maar dat doet de query op de achtergrond natuurlijk wel (want hoe moet ie anders komen aan COUNT(orderregels.id) en SUM(orgerregels.prijs)).

Daarom was mijn vraag hoe de query omgaat met klanten.naam, omdat ik daar verder geen aggregatie op toepas.
 
Joren de Wit

Joren de Wit

15/06/2009 16:39:00
Quote Anchor link
De vuistregel is duidelijk: groeperen op alle kolommen waarop je geen aggregatie functie toepast.

In sommige queries (en je huidige query ook) zal het geen invloed hebben op de uitkomst aangezien je ook groepeert op een gegeven dat andere groepen verder onder verdeelt (orders.id verdeelt klanten.naam verder). De groepen die gemaakt worden door het groeperen op order.id worden dus aangehouden. Maar voor een correcte query is het van belang dat je wel blijft groeperen op alle kolommen, dus ook op klanten.naam.
 

Pagina: « vorige 1 2



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.