Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Anfängerfrage - Alle Kunden Ausgeben

Dieses Thema im Forum "Oracle" wurde erstellt von DaSt1988, 20 Mai 2016.

  1. DaSt1988

    DaSt1988 Benutzer

    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
    Code:
    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
     
  2. akretschmer

    akretschmer Datenbank-Guru

    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?
     
  3. DaSt1988

    DaSt1988 Benutzer

    ja, ich habe schon bei allen drei joins einen left (outer) join versucht, bekomme aber trotzdem nur die, die einen Rahmen gekauft haben
     
  4. akretschmer

    akretschmer Datenbank-Guru

    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.
     
  5. DaSt1988

    DaSt1988 Benutzer

    Das ganze müssen wir aber in einen einzigen select befehl schreiben
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Ja, und?
     
  7. DaSt1988

    DaSt1988 Benutzer

    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
     
  8. akretschmer

    akretschmer Datenbank-Guru

    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?
     
  9. DaSt1988

    DaSt1988 Benutzer

    Ja, du meinst das left join, wenn ich das aber genauso mache bekomme ich wieder nur die als Ausgabe, die einen Rahmen gekauft haben.
    Code:
    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

    Code:
    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: 20 Mai 2016
  10. akretschmer

    akretschmer Datenbank-Guru

    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.
     
  11. DaSt1988

    DaSt1988 Benutzer

    danke, werds ausprobieren. Hab jetzt keine Zeit mehr
     
  12. akretschmer

    akretschmer Datenbank-Guru

    Macht nix, ich auch nicht ;-)
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden