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

Prozentualen Anteil ermitteln

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von DerMaddin, 29 November 2019.

  1. DerMaddin

    DerMaddin Benutzer

    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: 29 November 2019
  2. akretschmer

    akretschmer Datenbank-Guru

    bissl mager, Deine Kundentabelle ...
     
  3. akretschmer

    akretschmer Datenbank-Guru

    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?
     
  4. akretschmer

    akretschmer Datenbank-Guru

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

    DerMaddin Benutzer

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

    akretschmer Datenbank-Guru

    Tja, da gibt es 2 Möglichkeiten:

    • Du machst was falsch
    • MySQL macht was falsch

    Dritte Möglichkeit wäre noch beides ;-)
     
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