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

Select-Abfrage von 2 Werten mit unterschiedlichen Bedingungen möglich?

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Ramki, 18 Mai 2016.

  1. Ramki

    Ramki Benutzer

    Hallo liebe Forumsmitglieder,

    ich stehe mit SQL noch ziemlich am Anfang. Einfache Select, Insert oder Update-Befehle bekomme
    ich gerade so hin ... :)

    Jetzt stehe ich vor einem Problem, bei dem ich nicht weiterkomme:
    Ich hab eine Basistabelle mit den Spalten Kunde, Szenario, Jahr und Wert. Darauf möchte ich gerne
    eine Selektion, gruppiert nach 'Kunde' ausführen, die mir als Ergebnis 2 Werte nebeneinander (zum
    Vergleich) ausgibt, also z.B. 'Ist 2015' und 'Budget 2016'.
    Geht das irgendwie mit einer "verschachtelten Select-Anweisung" oder muss man mit CREATE tabel
    temporär neue Tabellen erzeugen?

    Anbei nochmal die Tabellenstruktur und das gewünschte Abfrageergebnis zur Veranschaulichung.
    Freue mich auf Tipps/Unterstützung.

    Vielen Dank, Ramki

    Tabelle:
    Kunde ......... Szenario ..... Jahr .....Wert
    Kunde_A .... Ist ............... 2015 ...... 15
    Kunde_A .... Budget ....... 2015 ...... 10
    Kunde_B .... Budget ....... 2016 ...... 8
    Kunde_C .... Ist ............... 2015 ...... 20
    Kunde_B .... Ist ............... 2016 ...... 12
    Kunde_A .... Ist ............... 2016 ...... 15
    Kunde_B .... Ist ............... 2015 ...... 10
    Kunde_C .... Budget ....... 2016 ...... 10
    Kunde_C .... Ist ............... 2015 ...... 20

    Gewünschtes Abfrage-Ergebnis:

    ..................................... (1.Wert = Ist 2015) ..... (2. Wert = Budget 2016)
    Kunde_A ..................... 15 ................................ 0
    Kunde_B .....................10 ................................. 8
    Kunde_C .....................40 ................................ 10
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Moin,

    möglicherweise geht das mit Deiner DB nicht:

    Code:
    test=*# select * from ramki ;
     kunde | szenario | jahr | wert
    -------+----------+------+------
     a  | i  | 2015 |  15
     a  | b  | 2015 |  10
     b  | b  | 2016 |  8
     c  | i  | 2015 |  20
     b  | i  | 2016 |  12
     a  | i  | 2016 |  15
     b  | i  | 2015 |  10
     c  | b  | 2016 |  10
     c  | i  | 2015 |  20
    (9 rows)
    
    test=*# select kunde, sum(wert) filter (where jahr = 2015 and szenario = 'i'), sum(wert) filter (where jahr=2016 and szenario = 'b') from ramki group by kunde order by kunde;
     kunde | sum | sum
    -------+-----+-----
     a  |  15 |   
     b  |  10 |  8
     c  |  40 |  10
    (3 rows)
    
    falls das nicht geht: subselects. Ist halt dann teurer, weil 2 Scans durch die Tabelle gehen.
     
    Ramki gefällt das.
  3. akretschmer

    akretschmer Datenbank-Guru

    hier ein weg, der auch bei nicht so leistungsfähigen Datenbanken wie PostgreSQL funktionieren sollte:

    Code:
    test=*# select distinct r.kunde, s1.sum, s2.sum from ramki r left join (select kunde, sum(wert) from ramki where jahr = 2015 and szenario = 'i' group by kunde) s1 on r.kunde=s1.kunde left join (select kunde, sum(wert) from ramki where jahr = 2016 and szenario = 'b' group by kunde) s2 on r.kunde=s2.kunde order by kunde;
     kunde | sum | sum
    -------+-----+-----
     a  |  15 |   
     b  |  10 |  8
     c  |  40 |  10
    (3 rows)
    
    
     
    Ramki gefällt das.
  4. akretschmer

    akretschmer Datenbank-Guru

    und kürzer dafür aber schöner:

    Code:
    test=*# select s1.kunde, s1.sum as "1.Wert Ist 2015", s2.sum as "2. Wert Budget 2016" from (select kunde, sum(wert) from ramki where jahr = 2015 and szenario = 'i' group by kunde) s1 left join (select kunde, sum(wert) from ramki where jahr = 2016 and szenario = 'b' group by kunde) s2 on s1.kunde=s2.kunde order by s1.kunde;
     kunde | 1.Wert Ist 2015 | 2. Wert Budget 2016
    -------+-----------------+---------------------
     a  |  15 |   
     b  |  10 |  8
     c  |  40 |  10
    (3 rows)
    
     
    Ramki gefällt das.
  5. Ramki

    Ramki Benutzer

    Hallo akretschmer,

    ganz lieben Dank für die Mühe, die Du dir gemacht hast. Ich habe alle 3 Lösungsansätze ausprobiert. Leider will nichts so recht funktionieren.

    Ich erhalte folgende Fehler:

    1. Möglichkeit (Die mit 'filter' = für mich am einfachsten nachvollziehbar):
    Incorrect syntax near the keyword 'where'.

    2. Möglichkeit (mit select distinct):
    No column name was specified for column 2 of 's1'.
    No column name was specified for column 2 of 's2'.


    3. Möglichkeit (mit einfügen von Spaltentiteln):
    No column name was specified for column 2 of 's1'.
    No column name was specified for column 2 of 's2'.
    Invalid column name 'sum'.

    Invalid column name 'sum'.


    Was mache ich denn bloß falsch?

    Danke, Gruß,
    Ramki

    PS: Ich bin auf dem MS SQL Server 2012 unterwegs ...
     
  6. akretschmer

    akretschmer Datenbank-Guru

    1. ist sicher die schönste Version, das kann aber wohl wirklich nur PostgreSQL, weil es die weltbeste Datenbank halt ist ;-)

    2. und 3. mußt halt mal sehen, daß Du den Spalten noch Aliase gibst. Zum beispiel der Spalte, die die Summe enthält. Bei PG bekommt die Spalte den Namen der Funktion, die diese erzeugt hat - hier sum(). Das mag in anderen Systemen so nicht gehen oder anders halt sein.
     
    Ramki gefällt das.
  7. akretschmer

    akretschmer Datenbank-Guru

    probier mal so, ob das hilft. das dürfte 3.) lösen:

    Code:
    test=*# select s1.kunde, s1.x as "1.Wert Ist 2015", s2.x as "2. Wert Budget 2016" from (select kunde, sum(wert) as x from ramki where jahr = 2015 and szenario = 'i' group by kunde) s1 left join (select kunde, sum(wert) as x from ramki where jahr = 2016 and szenario = 'b' group by kunde) s2 on s1.kunde=s2.kunde order by s1.kunde;
     kunde | 1.Wert Ist 2015 | 2. Wert Budget 2016
    -------+-----------------+---------------------
     a  |  15 |   
     b  |  10 |  8
     c  |  40 |  10
    (3 rows)
    
    
    Noch mal 'just for fun' die Ausführungspläne dafür und für die Filter-Variante:

    Code:
    test=*# explain select s1.kunde, s1.x as "1.Wert Ist 2015", s2.x as "2. Wert Budget 2016" from (select kunde, sum(wert) as x from ramki where jahr = 2015 and szenario = 'i' group by kunde) s1 left join (select kunde, sum(wert) as x from ramki where jahr = 2016 and szenario = 'b' group by kunde) s2 on s1.kunde=s2.kunde order by s1.kunde;
      QUERY PLAN   
    -------------------------------------------------------------------------------
     Sort  (cost=2.35..2.36 rows=1 width=18)
      Sort Key: ramki.kunde
      ->  Nested Loop Left Join  (cost=2.29..2.34 rows=1 width=18)
      Join Filter: (ramki.kunde = ramki_1.kunde)
      ->  HashAggregate  (cost=1.15..1.16 rows=1 width=6)
      Group Key: ramki.kunde
      ->  Seq Scan on ramki  (cost=0.00..1.14 rows=3 width=6)
      Filter: ((jahr = 2015) AND (szenario = 'i'::text))
      ->  HashAggregate  (cost=1.14..1.15 rows=1 width=6)
      Group Key: ramki_1.kunde
      ->  Seq Scan on ramki ramki_1  (cost=0.00..1.14 rows=1 width=6)
      Filter: ((jahr = 2016) AND (szenario = 'b'::text))
    (12 rows)
    
    test=*# explain select kunde, sum(wert) filter (where jahr = 2015 and szenario = 'i'), sum(wert) filter (where jahr=2016 and szenario = 'b') from ramki group by kunde order by kunde;  QUERY PLAN   
    ------------------------------------------------------------------
     Sort  (cost=1.30..1.31 rows=3 width=12)
      Sort Key: kunde
      ->  HashAggregate  (cost=1.25..1.28 rows=3 width=12)
      Group Key: kunde
      ->  Seq Scan on ramki  (cost=0.00..1.09 rows=9 width=12)
    (5 rows)
    
    Eindeutig, oder? (die Kosten sind hier bei der sehr kleinen Tabelle natürlich irrelevant und nicht wirklich vergleichbar, aber der Plan schon)
     
    Ramki gefällt das.
  8. Ramki

    Ramki Benutzer

    Perfekt, das hat's gelöst! Vielen Dank, "gefällt mir".
     
  9. akretschmer

    akretschmer Datenbank-Guru

  10. akretschmer

    akretschmer Datenbank-Guru

    was mir grad noch einfällt: du kannst auch das mit dem FILTER nachbauen, in etwa so:

    aus:
    sum(wert) filter (where jahr = 2015 and szenario = 'i'),

    machst du:
    sum(case when jahr = 2015 and szenario = 'i' then wert else 0 end) as ...


    Sollte auch mit Datenbanken gehen, die nicht so clever wie PG sind ...
     
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