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

Top 5 Werte pro Monat abfragen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von winscheil, 16 Juli 2021.

  1. winscheil

    winscheil Benutzer

    Hallo,
    ich möchte eine Abfrage bauen, die mir aus einer Tabelle immer die 3 höchsten Werte jedes Monats ausgibt.
    Datenaufbau:
    Monat Wert
    01 550
    01 200
    01 320
    01 600
    01 120
    02 800
    02 410
    02 150
    02 590
    02 730
    ...

    Die Ausgabe soll dann folgendes bringen:
    Monat Wert
    01 600
    01 550
    01 320
    02 800
    02 730
    02 590
    ...
    Ich kann zwar mit Top 3 die drei höchsten Werte einer ganzen Tabelle ausgeben.
    Aber ich weiß nicht, wie ich die Wiederholung für jeden Monat umsetzen kann.
    Kann mir da jemand helfen?
     
  2. akretschmer

    akretschmer Datenbank-Guru

    via LATERAL JOIN:

    Code:
    edb=*# select * from winscheil ;
     monat | wert
    -------+------
         1 |  550
         1 |  200
         1 |  320
         1 |  600
         2 |  800
         2 |  410
         2 |  150
         2 |  590
         2 |  730
    (9 rows)
    
    edb=*# select w.* from winscheil w left join lateral (select * from winscheil w2 where w2.monat = w.monat order by wert desc limit 2) x on (w.monat=x.monat and w.wert=x.wert) where x.monat is not null order by w.monat, w.wert;
     monat | wert
    -------+------
         1 |  550
         1 |  600
         2 |  730
         2 |  800
    (4 rows)
    
    edb=*#
    
     
  3. winscheil

    winscheil Benutzer

    vielen Dank für die schnelle Antwort.
    Das ist leider MSSQL. Da funktioniert LIMIT nicht.
    Und leider kenne ich das left join lateral auch nicht... funktioniert das bei MSSQL?
     
  4. Chuky666

    Chuky666 Datenbank-Guru

    Hallo winscheil,

    ja Left Join funzt auch im SQL-Server. :)
    Anstatt Limit nach DESC, nimmst du TOP 2 im SELECT. Beispiel: SELECT TOP 2 * FROM deine_tabelle usw
     
  5. akretschmer

    akretschmer Datenbank-Guru

    ja, aber eventuell ein left join LATERAL nicht ... ist SQL-Sdandard, aber nicht überall implementiert. Probier halt aus ...
     
  6. Chuky666

    Chuky666 Datenbank-Guru

    LATERAL dezent überlesen.... Sorry. Ja klar LEFT JOIN LATERAL im SQL-Server nein, aber LEFT JOIN ja :D
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Alternative Methode: mit row_number arbeiten, via 'partition my monat order by wert desc'. Nachteil: das wird komplett ausgeführt, während der LATERAL JOIN ... besser optimiert werden kann.
     
  8. Chuky666

    Chuky666 Datenbank-Guru

    Da fallen mir spontan GROUPING und CTE ein. Denke mit CTE dürfte es am "besten" gehen.
     
  9. akretschmer

    akretschmer Datenbank-Guru

    Code:
    edb=*# with tmp as (select monat, wert, row_number() over (partition by monat order by wert desc) from winscheil) select monat, wert from tmp where row_number <= 2 order by monat, wert desc;
     monat | wert
    -------+------
         1 |  600
         1 |  550
         2 |  800
         2 |  730
    (4 rows)
    
    
    wie gesagt, Nachteil wäre daß bei z.B. 1000 Werten je Monat alle gezählt und materilisiert werden (im CTE), dann aber 998 verworfen werden ...
     
  10. winscheil

    winscheil Benutzer

    was genau ist CTE?

    Ich hab jetzt mal den Select übernommen:
    with tmp as (select AUFTRAG,JAHR, KALENDERWOCHE, FINALE_KOSTEN, row_number() over (partition by AUFTRAG, JAHR, KALENDERWOCHE order by FINALE_KOSTEN desc) from ANP_FT_KALK_BEST_DASHBOARD)
    select AUFTRAG, JAHR, KALENDERWOCHE, FINALE_KOSTEN from tmp where row_number <= 2 and AUFTRAG = '207201' order by JAHR, KALENDERWOCHE, FINALE_KOSTEN desc

    Da bekomme ich folgende Fehlermeldung:
    Kein Spaltenname wurde für die Spalte 5 von "tmp" angegeben.

    Ich muss nach Auftrag, Jahr und Kalenderwoche unterscheiden.
    Finale_Kosten ist der Wert, den ich brauche.
    Und hier die 2 höchsten Werte in jeder Kalenderwoche von jedem Jahr, die in dem Auftrag sind.
    Habe das mit Monat einfachhalber am Anfang erklärt...

    Was mach ich bei der Abfrage falsch?
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Abkürzung für Common Table Expressions.
     
  12. castorp

    castorp Datenbank-Guru

    Microsoft hat sich entschieden den SQL Standard zu ignorieren, deswegen kochen sie ihr eigenen Süppchen und haben beschlossen dass "APLLY" besser ist als "LATERAL.

    Das Äquivalent zu LEFT JOIN LATERAL in T-SQL ist deswegen OUTER APPLY
     
    akretschmer gefällt das.
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