JOIN mit 3 Tabellen

DerMaier

Neuer Benutzer
Beiträge
2
Ich habe drei Tabellen. Artikel, Posten und Bestellzeilen. Ich möchte jetzt zählen, wie viele Posten und wie viele Bestellzeilen es gibt.

Code:
artikel
=======
nr    beschreibung
85    Hohlstecker

artikelposten
======
id    artnr    menge
120    85    2
204    85    4


bestellzeilen
============
id    artnr    menge
131    85    2
224    85    4


Wunsch
======
Ich möchte wissen, welchen Artikel ich wie oft in den Posten habe und wie oft in den Bestellzeilen.



Code:
Wunsch-Ergebnis mit SUM() und GROUP BY
======================================
id    bestellmenge    postenmenge
85    6        6

Wunsch-Zwischen-Ergebnis ohne SUM() und ohne GROUP BY
=====================================================
nr    beschreibung    id    menge    id    menge
85    Hohlstecker    120    2    NULL    NULL
85    Hohlstecker    204    4    NULL    NULL
85    Hohlstecker    NULL    NULL    131    2
85    Hohlstecker    NULL    NULL    224    4



IDEE 1
======
Meine erste Idee war, alles mit JOIN zu verbinden. dann jedoch werden die Ergebnisse miteinander "multipliziert" und ich bekomme zu viele Zeilen und somit zu große Zahlen.

IDEE 2
======
Meine zweite Idee war, zwei getrennte Abfragen zu machen und diese mit UNION zu verbinden. Ohne GROUP BY ist das Ergebnis sehr gut, aber es lässt sich dann nicht mehr gruppieren. Man kann nur beide Abfragen separat Gruppieren und UNION liefert dann zwei Zeilen. Außerdem muss man "Leere Spalten" einfügen, damit man im Ergebnis sehen kann, ob es eine Bestellmenge oder eine Postenmenge ist.


Hilfslösung
===========
Meine aktuelle Hilfslösung ist, daß ich drei SQL-Abfragen mache. Die erste ließt nur die Bestellmengen ab und speichert das Ergebnis in ein Array (PHP). Die zweite macht gleiches mit den Postenmengen. Und die dritte ist dann die eigentliche Hauptabfrage, welche mir alle Daten liefert. Und beim Ausgeben an den Browser hole ich die fehlenden Daten dann aus den Arrays. Das ganze funktioniert zwar sehr zuverlässig. Aber jetzt soll alles mit ORDER BY erweitert werden. Ich kann in der Hauptabfrage auf alle Ergebnissspalten sortieren, je nachdem was der User sehen möchte. Nur wenn ich nach Bestellmenge sortieren möchte, geht das nicht mehr, da die Bestellmenge in einem Array steht. Ich möchte auf keinen Fall erst alle Daten in Arrays laden und dann mit PHP alles lösen. Das geht Sinn von SQL vorbei. Es gibt auch noch mehr als nur "Bestellzeilen" und "Posten", hier soll später noch einges erweitert werden.



Code:
SQL 1 ohne GROUP
================
SELECT * FROM artikel
LEFT JOIN artikelposten ON artikel.nr = artikelposten.artikelnummer
LEFT JOIN bestellzeilen ON artikel.nr = bestellzeilen.artikel

Ergebnis 1
==========
nr    beschreibung    id    menge    id    menge
85    Hohlstecker    120    2    131    2
85    Hohlstecker    120    2    224    4
85    Hohlstecker    204    4    131    2
85    Hohlstecker    204    4    224    4



SQL 1 mit GROUP
===============
SELECT artikel.nr,artikel.beschreibung,sum(bestellzeilen.menge) ,sum(artikelposten.menge) as postenmenge
FROM artikel
LEFT JOIN artikelposten ON artikel.nr = artikelposten.artikelnummer
LEFT JOIN bestellzeilen ON artikel.nr = bestellzeilen.artikel
GROUP BY artikel.nr

Ergebnis
========
id    bestellmenge    postenmenge
85    12        12



SQL 2
=====
SELECT artikel.nr,artikel.beschreibung,NULL as bestellmenge,artikelposten.id, artikelposten.menge as postenmenge
FROM artikel LEFT JOIN artikelposten ON artikel.nr = artikelposten.artikelnummer
UNION
SELECT artikel.nr,artikel.beschreibung, bestellzeilen.id,bestellzeilen.menge as bestellmenge, NULL as postenmenge
FROM artikel LEFT JOIN bestellzeilen ON artikel.nr = bestellzeilen.artikel

Ergebnis
========
nr    beschreibung    id    menge    id    menge
85    Hohlstecker    120    2    NULL    NULL
85    Hohlstecker    204    4    NULL    NULL
85    Hohlstecker    NULL    NULL    131    2
85    Hohlstecker    NULL    NULL    224    4



SQL 2 mit GROUP BY
==================
SELECT artikel.nr,artikel.beschreibung, 
sum(artikelposten.menge) as postenmenge,
NULL as bestellmenge 
FROM artikel 
LEFT JOIN artikelposten ON artikel.nr = artikelposten.artikelnummer
GROUP BY artikel.nr

UNION 

SELECT artikel.nr,artikel.beschreibung,
NULL as postenmenge,
sum(bestellzeilen.menge) as bestellmenge
FROM artikel
LEFT JOIN bestellzeilen ON artikel.nr = bestellzeilen.artikel
GROUP BY artikel.nr

Ergebnis
========
nr    beschreibung    menge    menge
85    Hohlstecker    6    NULL
85    Hohlstecker    NULL    6
 
Werbung:
Ich habe drei Tabellen. Artikel, Posten und Bestellzeilen. Ich möchte jetzt zählen, wie viele Posten und wie viele Bestellzeilen es gibt.

Wunsch
======
Ich möchte wissen, welchen Artikel ich wie oft in den Posten habe und wie oft in den Bestellzeilen.



Code:
Wunsch-Ergebnis mit SUM() und GROUP BY
======================================
id    bestellmenge    postenmenge
85    6        6

Code:
test=*# select a.nr, a.beschreibung, (select sum(menge) from bestellzeilen where artnr=a.nr) bestellmenge, (select sum(menge) from artikelposten where artnr=a.nr) postenmenge from artikel a;
 nr | beschreibung | bestellmenge | postenmenge
----+--------------+--------------+-------------
 85 | Hohlstecker  |  6 |  6
(1 row)
 
Danke akretschmer, das hat funktioniert. Es ist jedoch ziemlich "anders" als mit Joins zu arbeiten, ich bin gerade dabei die ganze große Abfrage entsprechend abzuändern. Probleme macht das ganze noch, wenn noch eine weitere Ebene hinzukommt (z.B. "offene Bestellzeilen"), aber mal schauen, ich baue erstmal die anderen Punkte so mit ein.
 
Werbung:
Danke akretschmer, das hat funktioniert. Es ist jedoch ziemlich "anders" als mit Joins zu arbeiten, ich bin gerade dabei die ganze große Abfrage entsprechend abzuändern. Probleme macht das ganze noch, wenn noch eine weitere Ebene hinzukommt (z.B. "offene Bestellzeilen"), aber mal schauen, ich baue erstmal die anderen Punkte so mit ein.

Du kannst auch mit JOIN arbeiten, da mußt Du aber erst mal aggregieren und dann damit joinen.
 
Zurück
Oben