Prozentualen Anteil ermitteln

DerMaddin

Benutzer
Beiträge
5
Hallo,
ich möchte den prozentualen Anteil von Aufträgen je Kunde gemessen an der Gesamtzahl von Aufträgen ermitteln. Leider komme ich nicht weiter, ich denke es hakt an der Gruppierung auf den Kunden

Folgende Tabellen sind gegeben:
Tabelle "Kunde"
kundeID
kunde

Tabelle Auftrag
auftragID
datum
kundeID (Fremdschlüssel)

Das soll rauskommen
Kunde | Anteil in %
Meier | 8
Müller | 12
Schulz | 4

Damit habe ich es versucht. Ich bekomme zwar einen %-Wert, aber der ist für alle Kunden gleich:
SELECT kunde,
(SELECT COUNT(*) FROM auftrag JOIN kunde ON auftrag.kundeID = kunde.kundeID) * (SELECT COUNT(*) FROM auftrag) / 100 AS "Anteil in %"
FROM kunde
GROUP BY kundeID

Hat jemand eine Idee, wie man das lösen kann?

Danke & Gruß
 
Zuletzt bearbeitet:
Werbung:
Das Ursprungsposting im Nachgang massiv zu ändern ist a bissl ... nun ja.

Angenommen, Du hast diese Tabelle:

Code:
test=*# select * from kunde;
 id | auftrag
----+---------
  1 |       1
  1 |       2
  1 |       3
  2 |       4
  2 |       5
  1 |       6
(6 rows)

id mag ein FK sein, und auftrag möge die Auftragsnummer sein.

Code:
test=*# select id, count(*), count(*)::numeric * 100 / (select count(*) from kunde)  as anteil from kunde group by id order by id;
 id | count |       anteil       
----+-------+---------------------
  1 |     4 | 66.6666666666666667
  2 |     2 | 33.3333333333333333
(2 rows)

Kommst Du damit weiter?
 
Eine elegantere Variante wäre der Einsatz von Window-Funktionen, das wäre kostengünstiger. Hier mal beide Varianten mit EXPLAIN ANALYSE:

Code:
test=*# explain analyse select id, count(*), count(*)::numeric * 100 / (select count(*) from kunde)  as anteil from kunde group by id order by id;
                                                     QUERY PLAN                                                     
---------------------------------------------------------------------------------------------------------------------
 Sort  (cost=2.24..2.25 rows=2 width=44) (actual time=0.061..0.061 rows=2 loops=1)
   Sort Key: kunde.id
   Sort Method: quicksort  Memory: 25kB
   InitPlan 1 (returns $0)
     ->  Aggregate  (cost=1.07..1.08 rows=1 width=8) (actual time=0.011..0.011 rows=1 loops=1)
           ->  Seq Scan on kunde kunde_1  (cost=0.00..1.06 rows=6 width=0) (actual time=0.004..0.006 rows=6 loops=1)
   ->  HashAggregate  (cost=1.10..1.15 rows=2 width=44) (actual time=0.047..0.051 rows=2 loops=1)
         Group Key: kunde.id
         ->  Seq Scan on kunde  (cost=0.00..1.06 rows=6 width=4) (actual time=0.009..0.011 rows=6 loops=1)
 Planning Time: 0.243 ms
 Execution Time: 0.131 ms
(11 rows)

test=*# explain analyse select distinct id, (count(*) over (partition by id rows between unbounded preceding and unbounded following))::numeric * 100 / count(auftrag) over (order by id rows between unbounded preceding and unbounded following) from kunde;
                                                         QUERY PLAN                                                         
-----------------------------------------------------------------------------------------------------------------------------
 Unique  (cost=1.47..1.52 rows=6 width=36) (actual time=0.127..0.135 rows=2 loops=1)
   ->  Sort  (cost=1.47..1.49 rows=6 width=36) (actual time=0.126..0.127 rows=6 loops=1)
         Sort Key: id, (((((count(*) OVER (?)))::numeric * '100'::numeric) / (count(auftrag) OVER (?))::numeric))
         Sort Method: quicksort  Memory: 25kB
         ->  WindowAgg  (cost=1.14..1.39 rows=6 width=36) (actual time=0.063..0.077 rows=6 loops=1)
               ->  WindowAgg  (cost=1.14..1.24 rows=6 width=16) (actual time=0.037..0.046 rows=6 loops=1)
                     ->  Sort  (cost=1.14..1.15 rows=6 width=8) (actual time=0.021..0.022 rows=6 loops=1)
                           Sort Key: id
                           Sort Method: quicksort  Memory: 25kB
                           ->  Seq Scan on kunde  (cost=0.00..1.06 rows=6 width=8) (actual time=0.010..0.012 rows=6 loops=1)
 Planning Time: 0.228 ms
 Execution Time: 0.218 ms
(12 rows)

test=*#

Wie man sieht ist hier nur ein Scan der Tabelle nötig, daher sind dann auch die Kosten besser.
 
erstmal besten Dank.
Die Kundentabelle wurde von mir zur besseren Übersichtlichkeit gekürzt (sie ist tatsächlich umfangreicher).

Ich habe Dein Code-Beispiel

Code:
select id, count(*), count(*)::numeric * 100 / (select count(*) from kunde)  as anteil from kunde group by id order by id;

mal ausprobiert, aber ich bekomme für jeden Kunden den gleichen Prozentwert, obwohl die Anzahl der Aufträge je Kunde unterschiedlich ist.

Gruß
Maddin
 
Werbung:
Zurück
Oben