Anfängerfrage - Alle Kunden Ausgeben

DaSt1988

Benutzer
Beiträge
13
Hallo,

ich versuche seit einiger Zeit vergebens folgende Aufgabe komplett zu lösen.

Wie viele Rahmen haben die Kunden im Jahr 2014 in Auftrag gegeben? Schreiben Sie einen entsprechenden Select-Befehl, der alle!! Kunden absteigend nach der Anzahl der in Auftrag gegebenen Rahmen ausgibt
Wichtig:
-Die Spaltenüberschriften lauten: Kundennr, Kundenname, Anzahl
-Kunden die im Jahr 2014 keine Rahmen gekauft haben, werden mit Anzahl 0 gelistet
-Datumsangaben dürfen nciht länderabhängig sein

Bei mir werden nur die ausgegeben, die einen Rahmen gekauft haben, aber ich bekomme es nicht hin, dass die anderen mit 0 gelistet werden.

Mein Befehl
SQL:
Select kunde.nr as Kundennr, kunde.name as Kundenname, coalesce(Auftragsposten.Anzahl,0) as Anzahl
from kunde left outer join auftrag on (kunde.nr = auftrag.kundnr)
  inner join auftragsposten on (auftrag.auftrnr = auftragsposten.auftrnr)
  inner join artikel on(artikel.anr=Auftragsposten.Artnr)
where Artikel.Bezeichnung like'%Rahmen%' and auftrag.DATUM between to_date('01.01.2014','DD.MM.YYYY') and to_Date('31.12.2014','DD.MM.YYYY')
order by Anzahl desc;

Relation Kunde hat folgende Spalten:
NR|Name|strasse|plz|ort|sperre

Relation auftrag
auftrnr|datum|kundnr|persnr

relation auftragsposten
posnr|auftrnr|artnr|anzahl|gesamtpreis|einzelpreis

relation artikel
anr|bezeichnung|netto|steuer|preis|farbe|mass|einheit|typ|

Wie gesagt, die Kunden, die einen Rahmen gekauft haben werden korrekt ausgegeben, nur die, die keinen gekauft haben werden nicht angezeigt.
Was mache ich falsch und was ist mit dem teil der Angabe gemeint in dem steht "Datumsangaben dürfen nicht länderabhängig sein"?

Vielen Dank für eure Bemühungen
 
Werbung:
ein INNER JOIN liefert die, die auf beiden Seiten was haben. Was Du suchst ist, daß auf der einen Seite der Kunde steht und auf der anderen entweder die Anzahl oder, falls da nix ist, NULL oder 0. Da böte sich ein LEFT JOIN an. Die Syntax findest Du ganz sicher, oder?
 
ja, ich habe schon bei allen drei joins einen left (outer) join versucht, bekomme aber trotzdem nur die, die einen Rahmen gekauft haben
 
works for me:

Code:
test=*# create table kunde (id int primary key, name text);
CREATE TABLE
test=*# create table auftrag (kunde int references kunde, menge int);
CREATE TABLE
test=*# insert into kunde values (1, 'kunde 1');
INSERT 0 1
test=*# insert into kunde values (2, 'kunde 2');
INSERT 0 1
test=*# insert into auftrag values (1, 10);
INSERT 0 1
test=*# insert into auftrag values (1, 5);
INSERT 0 1
test=*# select * from kunde k inner join auftrag a on k.id=a.kunde;
 id |  name  | kunde | menge
----+---------+-------+-------
  1 | kunde 1 |  1 |  10
  1 | kunde 1 |  1 |  5
(2 rows)

test=*# select * from kunde k left join auftrag a on k.id=a.kunde;
 id |  name  | kunde | menge
----+---------+-------+-------
  1 | kunde 1 |  1 |  10
  1 | kunde 1 |  1 |  5
  2 | kunde 2 |  |   
(3 rows)

test=*# select k.id, k.name, coalesce(sum(a.menge),0) from kunde k left join auftrag a on k.id=a.kunde group by k.id, k.name;
 id |  name  | coalesce
----+---------+----------
  2 | kunde 2 |  0
  1 | kunde 1 |  15
(2 rows)


Dein Schema ist größer, ich weiß, aber das Prinzip ist gleich. Ach ja: Du solltest aggregieren, also die Aufträge.
 
Ich dachte das spielt eine Rolle.
Ich verstehe nicht wo bei meinem obrigen select Befehl der Fehler liegt, ich habe dort zwischen Kunde und Auftrag einen Left Join genau wie du, ebenso verwende ich coalesce,dass wenn keine Anzahl vorhanden ist, 0 eingetragen werden soll
 
also...

Code:
test=*# select * from kunde ;
 nr | name  | strasse | plz | ort | sperre
----+-------+---------+-----+-----+--------
  1 | name1 |  |  |  |   
(1 row)

test=*# select * from auftrag;
 auftrnr | datum | kundnr | persnr
---------+-------+--------+--------
(0 rows)

test=*# select * from auftragsposten ;
 posnr | auftrnr | artnr | anzahl | gesamtpreis | einzelpreis
-------+---------+-------+--------+-------------+-------------
(0 rows)

test=*# select * from artikel;
 anr | bezeichnung | netto | steuer | preis
-----+-------------+-------+--------+-------
(0 rows)

test=*# Select kunde.nr as Kundennr, kunde.name as Kundenname, coalesce(Auftragsposten.Anzahl,0) as Anzahl
from kunde left outer join auftrag on (kunde.nr = auftrag.kundnr)
  inner join auftragsposten on (auftrag.auftrnr = auftragsposten.auftrnr)
  inner join artikel on(artikel.anr=Auftragsposten.Artnr)
where true
order by Anzahl desc;
 kundennr | kundenname | anzahl
----------+------------+--------
(0 rows)

test=*# Select kunde.nr as Kundennr, kunde.name as Kundenname, coalesce(Auftragsposten.Anzahl,0) as Anzahl
from kunde left outer join auftrag on (kunde.nr = auftrag.kundnr)
  left join auftragsposten on (auftrag.auftrnr = auftragsposten.auftrnr)
  left join artikel on(artikel.anr=Auftragsposten.Artnr)
where true
order by Anzahl desc;
 kundennr | kundenname | anzahl
----------+------------+--------
  1 | name1  |  0
(1 row)

test=*#

Du findest den Unterschied?
 
Ja, du meinst das left join, wenn ich das aber genauso mache bekomme ich wieder nur die als Ausgabe, die einen Rahmen gekauft haben.
SQL:
Select kunde.nr as Kundennr, kunde.name as Kundenname, coalesce(Auftragsposten.Anzahl,0) as Anzahl
from kunde left outer join auftrag on (kunde.nr = auftrag.kundnr)
  left join auftragsposten on (auftrag.auftrnr = auftragsposten.auftrnr)
  left join artikel on(artikel.anr=Auftragsposten.Artnr)
  where Artikel.Bezeichnung like '%Rahmen%' and auftrag.DATUM between to_date('01.01.2010','DD.MM.YYYY') and to_Date('31.12.2014','DD.MM.YYYY')
order by Anzahl desc;

habe den Befehl mal ohne die where-klausel versucht also so

SQL:
Select kunde.nr as Kundennr, kunde.name as Kundenname, coalesce(Auftragsposten.Anzahl,0) as Anzahl
from kunde left outer join auftrag on (kunde.nr = auftrag.kundnr)
  left join auftragsposten on (auftrag.auftrnr = auftragsposten.auftrnr)
  left join artikel on(artikel.anr=Auftragsposten.Artnr)
order by Anzahl desc;

Hier werden jetzt aber alle Kunden ausgegeben die irgendetwas gekauft haben und die die nichts gekauft haben werden mit 0 angezeigt, ich muss dass aber einschränken auf die Rahmen
Dass nur bei denen die einen Rahmen gekauft haben die Anzahl dasteht und bei allen anderen 0

Danke für deine Geduld
 
Zuletzt bearbeitet:
ahhhh, ich glaube, ich verstehe nun langsam dein Problem. Lasse die where-condition weg und ändere im select das auf

case when artikel.bezeichnung like '%rahmen%' then anzahl else 0 end

damit filterst Du dann an dieser Stelle. Und ja, ich denke, du willst das noch aggregieren. Aber das sagte ich ja schon.
 
Werbung:
Zurück
Oben