SQL - Abfrage (logik problem)
Andre
- datenbank
Morgen zusammen,
ich habe da ein Problem.
(Gleich vorweg, ich habe keine Einfluß auf die Datenbank-Struktur!)
Folgenden SQL-Befehl habe ich geschrieben und bin eigentlich damit zufrieden:
SELECT
Tabelle4.wert,sum(Tabelle2.menge) AS Menge
FROM
Tabelle1,Tabelle2,Tabelle3,Tabelle4
WHERE
Tabelle1.lieferdatum>="2007-01-01"
AND
Tabelle1.lieferdatum<"2007-02-01"
AND
Tabelle2.auftrag_id=Tabelle1.id
AND
Tabelle3.id=Tabelle2.produkt_id
AND
Tabelle4.produkt_id=Tabelle3.id
AND
Tabelle4.name='länge'
GROUP BY
Tabelle4.wert
ORDER BY
Menge
DESC
Als Ergebniss bekomme ich dann folgendes geliefert:
wert menge
------ -----
300.0 154.0
150.0 114.0
200.0 81.0
140.0 54.0
usw...
Ok. Nun möchte ich noch folgendes haben...
Folgender Fall kann eintreten:
Tabelle4.name='länge' kann auch "farbe" enthalten, also: Tabelle4.name='farbe'
Wie muss ich meinen SQL-Befehl erweitern um folgendes als Ergebniss geliefert zu bekommen:
p_wert farbe menge
------ ----- -----
300.0 grün 100.0
300.0 rot 34.0
300.0 gelb 20.0
150.0 grün 100.0
150.0 gelb 14.0
200.0 grün 81.0
usw...
Ich komm einfach nicht drauf. Ich glaube die schwierigkeit daran ist das "länge" und "farbe" in einem Feld stehen und ich ja nur nach "farbe" nochmal "Untergruppieren" will.
Vieleicht kann mir ja jemand helfen, ich komm da einfach nicht drauf.
Wäre klasse.
Gruß
Andre
Hi,
zeichne mal bitte die Strukturen der einzelnen Tabellen hier auf, mit Beispielinhalten
Welches Datenbanksystem und welche Version davon
Deine jetzige Problembeschreibung enthält zuviel Ungenauigkeiten.
Gruss, Frank
- zeichne mal bitte die Strukturen der einzelnen Tabellen hier auf, mit Beispielinhalten
Tabelle: auftrag
id
lieferdatum
Tabelle: auftragposition
id
auftrag_id
produkt_id
menge(z.b. 1 oder 3 usw...)
Tabelle: produkt
id
Tabelle: produkteigenschaft
produkt_id
wert
(Wenn Feld: name="länge" dann enthält Feld: wert z.b. 120 oder 240 usw...)
(Wenn Feld: name="farbe" dann enthält Feld: wert z.b. grün oder rot usw...)
name (enthält "länge" oder "farbe")
Das ist die bisherige SQL Abfrage:
SELECT
produkteigenschaft.wert,sum(auftragposition.menge) AS Menge
FROM
auftrag,auftragposition,produkt,produkteigenschaft
WHERE
auftrag.lieferdatum>="2007-01-01"
AND
auftrag.lieferdatum<"2007-02-01"
AND
auftragposition.auftrag_id=auftrag.id
AND
produkt.id=auftragposition.produkt_id
AND
produkteigenschaft.produkt_id=produkt.id
AND
produkteigenschaft.name='länge'
GROUP BY
produkteigenschaft.wert
ORDER BY
Menge
DESC
Ausgabe:
wert menge
------ -----
300.0 154.0
150.0 114.0
200.0 81.0
140.0 54.0
usw...
- Welches Datenbanksystem und welche Version davon
Informix, aktuellste Version
Deine jetzige Problembeschreibung enthält zuviel Ungenauigkeiten.
hoffe die konnte ich jetzt etwas bereinigen
Gruss, Frank
Danke Gruß
Wahrscheinlich ist das doch nicht machbar.
Hab ich mir fast gedacht. Schade.
SQL kann halt nicht alles ;-)
Falls es doch machbar ist Ihr aber noch nicht ganz versteht was mein Problem ist dann fragt bitte einfach nochmal.
Aber ich denke ich hab das im letzten Post doch ganz verständlich aufgezeigt.
Vielen Dank.
Gruß
Oder jetzt mal ganz anders gefragt, vieleicht war das erste Beispiel einfach zu komplex/kompliziert!
Hoffe das ich es so besser und verständlicher erklären kann:
Tabelle A
id wert name menge*
-----------------------
0 rot farbe 1
1 gelb farbe 2
0 100 länge 1
1 100 länge 2
2 rot farbe 4
2 500 länge 4
3 800 länge 1
3 lila farbe 1
*Menge kommt aus einer anderen Tabelle ist dort eindeutig.
Hier im Beispiel steht halt bei id 0, farbe rot und bei id 0, länge 100 jeweils 1 obwohl die 1 natürlich für beide zusammen gilt.
draus soll folgendes Ergebniss angezeigt werden:
id länge farbe menge
------------------------
0 100 rot 1
1 100 gelb 2
2 500 rot 4
3 800 lila 1
länge und farbe sind im selben Feld darin sehe ich eben das Problem.
Gibt es dafür eine lösung das so zu gruppieren und anzeigen zu lassen?
Danke.
Hi,
Informix sagt mir primär nix, ausser dass es quasi von IBM stammt.
Ich hoffe, es unterstützt SQL nach ANSI 92 Standard und damit explizite JOIN syntax. Mit letzterer wird dein SQL auch viel deutlicher lesbar.
SELECT
pe1.wert,
pe2.wert,
sum(auftragposition.menge) AS Menge
FROM produkt
INNER JOIN produkteigenschaft pe1
ON produkt.id = pe1.produkt_id
-- und jetzt nur die Produkteingeschaften LÄNGE
AND pe1.Name = 'länge'
INNER JOIN produkteigenschaft pe2
ON produkt.id = pe2.produkt_id
-- und jetzt nur die Produkteingeschaften FARBE
AND pe2.Name = 'farbe'
INNER JOIN auftragposition
ON produkt.id = auftragposition.produkt_id
INNER JOIN auftrag
ON auftragposition.auftrag_id = auftrag.id
AND auftrag.lieferdatum BETWEEN "2007-01-01" AND "2007-02-01"
GROUP BY pe1.wert,
pe2.wert
ORDER BY Menge DESC
Du musst also die Tabelle 'produkteigenschaft' 2x joinen.
Gruss, Frank
Also ersteinmal ein großes Dankeschön!
Hab nicht erwartet das du mir gleich den ganzen Code lieferst ;-)
Aber es funktioniert einwandfrei, genau so wie ich es wollte.
Mich jetzt nicht undankbar einschätzen, aber ich würde es auch gerne vollständig verstehen ;-)
[code lang=sql]
SELECT
pe1.wert,
pe2.wert,
hier werden doch Aliasnamen erstellt oder?
Ich wusste gar nicht das so funktioniert...
sum(auftragposition.menge) AS Menge
FROM produktd
INNER JOIN produkteigenschaft pe1
Bedeutet das, dass du ein Ergebniss nur für die Variable pe1 holst?
ON produkt.id = pe1.produkt_id
-- und jetzt nur die Produkteingeschaften LÄNGE
AND pe1.Name = 'länge'
INNER JOIN produkteigenschaft pe2
Und hier wird das Ergebniss mit farbe in die Variable pe2 geschrieben, oder?
ON produkt.id = pe2.produkt_id
-- und jetzt nur die Produkteingeschaften FARBE
AND pe2.Name = 'farbe'
INNER JOIN auftragposition
ON produkt.id = auftragposition.produkt_id
Wo ist auf Übersichtlicher Betrachtung JOIN besser als ohne?
Ohne wäre ja dann:
oben bei SELECT die tabellen auftragposition,produkt schreiben
und dann in der WHERE Klausel produkt.id = auftragposition.produkt_id. Oder sehe ich da was falsch?
INNER JOIN auftrag
ON auftragposition.auftrag_id = auftrag.id
AND auftrag.lieferdatum BETWEEN "2007-01-01" AND "2007-02-01"
Ok BETWEEN ist natürlich besser als das vorherige ;-)
GROUP BY pe1.wert,
pe2.wert
ORDER BY Menge DESC
Du musst also die Tabelle 'produkteigenschaft' 2x joinen.
Ja genau, aber ich wusste nicht wie *g*
Gruss, Frank
Hi nochmal,
»»»» SELECT
»»»» pe1.wert,
»»»» pe2.wert,
hier werden doch Aliasnamen erstellt oder?
Ich wusste gar nicht das so funktioniert...
Nein, da werden keine Aliasnamen _erstellt_ sondern hier:
INNER JOIN produkteigenschaft pe1
INNER JOIN fügt eine Referenz auf die Tabelle unter dem Alias "pe1" dem Resultset hinzu. Die Spalten der Datensätz von produkteigenschaft, die dem JOIN entsprechen, stehen dann als pe1 zur Verfügung.
»»»» INNER JOIN produkteigenschaft pe1
»»»» ON produkt.id = pe1.produkt_id
»»»» -- und jetzt nur die Produkteingeschaften LÄNGE
»»»» AND pe1.Name = 'länge'
Bedeutet das, dass du ein Ergebniss nur für die Variable pe1 holst?
Nicht ganz, es bedeutet ich hole alle Datensätze aus 'produkteigenschaft', deren .Name = 'länge' ist als Tabelle in meine Abfrage und nenne sie pe1.
Warum das Aliasing? Weil du 2x dieselbe Tabelle joinst/brauchst und die DB ohne die unterschiedlichen Aliasnamen nicht wüsste aus welcher Menge eine bestimmte Spalte zu selektieren ist.
Warum explizite JOIN Syntax besser ist?
Gruss, Frank
ok, danke schön.
Bin auch gerade dabei mir das ganze mit den JOINS durchzulesen und zu lernen/verstehen.
Bis jetzt hab ich JOINS immer ignoriert ;-)
Dank dir auch jedenfall für dein Hilfe.
Gruß
schönen Abend noch...