Die relevantesten Datensätze gruppieren

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Antworten
Benutzeravatar
martin.koeditz
Beiträge: 448
Registriert: Sa 31. Mär 2018, 14:35

Hallo zusammen,

ich suche einen eleganten Weg mir die 10 wichtigsten Datensätze anzeigen zu lassen und alles andere unter "sonstige" laufen zu lassen. Ähnlich wie bei Wahlen.

Also konkret:
Tickets zu Mitarbeitern werden in der Tabelle TBL_TICKETS geführt. Jedes Ticket ist einem Mitarbeiter aus der Tabelle TBL_EMPLOYEES zugeordnet. Nun möchte ich die 10 Mitarbeiter mit den meisten Tickets anzeigen und den Rest unter sonstige laufen lassen.

Über diesen Weg bekomme ich ja alle Datensätze bis zum letzten Mitarbeiter.

Code: Alles auswählen

SELECT EMPLOYEE_NAME, COUNT(TICKET_ID) AS ANZAHL
FROM TBL_TICKETS T
INNER JOIN TBL_EMPLOYEES E ON T.EMPLOYEE_ID = E.EMPLOYEE_ID
ORDER BY 2 DESC
Hat jemand einen besseren Ansatz?

Dank und Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 492
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Auseinandernehmen kannst du das dann ja

Code: Alles auswählen

select
       g.Firma
      ,top10
      ,count(distinct g."Produkt") AnzahlProdukte
  from (

   select
        case when r.rang > 10 then 'Alle' else r."Firma" end Firma
       ,case when r.rang > 10 then 9999 else r.rang end Top10
       ,r."Produkt"

    from (

     select a.*
     ,dense_rank() over(order by Anzahl desc) rang

      from (

        select a."Firma"
             ,a."Produkt"
             ,count(*) over(partition by a."Firma") Anzahl
          from "Umsatz Anselm View" a
        where not a."Firma" is null
            and not a."Produkt" is null

      ) a

   ) r

) g

group by 1, 2
order by top10
Viel Spaß
vr2
Beiträge: 219
Registriert: Fr 13. Apr 2018, 00:13

Hi Martin, nimm mal das hier:

Code: Alles auswählen

-- umgruppieren und Summe 'sonstige' berechnen, alle anderen Summen sind wegen Dimension name = anzahl
select iif(rang > 10, 'sonstige', name) name, sum(anzahl) summe
from (
  -- anzahl und rang über anzahl absteigend berechnen 
  -- außerdem in rang durch Zweitsortierung nach name für stabile Sortierung sorgen, falls Anzahlen gleich sind
  select e.employee_name name, count(t.ticket_id) anzahl, dense_rank() over (order by count(t.ticket_id) desc, e.employee_name) rang
  from tbl_tickets t
  join tbl_employees e on e.employee_id = t.employee_id
  group by 1
)
group by 1
order by min(rang)
Grüße, Volker
bfuerchau
Beiträge: 492
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Ja, tatsächlich eleganter.
Ich hatte vergessen, dass man ja beim Order By auch Ausdrücke verwenden kann. Das spart dann verschachtelte Ebenen ein.
vr2
Beiträge: 219
Registriert: Fr 13. Apr 2018, 00:13

@bfuerchau: ja, mit aktuellem SQL sind solche Fragestellungen so elegant und performant zu lösen, das macht einfach Freude.
@Martin: Hattest Du schon die Gelegeheit , das mal zu testen?
Benutzeravatar
martin.koeditz
Beiträge: 448
Registriert: Sa 31. Mär 2018, 14:35

Hallo Volker,

habe ich noch nicht getestet. Da komme ich vermutlich erst Ende der Woche zu. Ich gebe dann nochmal Rückmeldung.

Dank und Gruß
Martin
Martin Köditz
it & synergy GmbH
Antworten