Beate Mielke: wie Zahlen in Prozentzahlen umwandeln

Hallo ForumerInnen,

verschiedene Menschen können sich ein oder mehrere Obstsorten aussuchen.
Dadurch entsteht die folgende Datenbank:

Obst            Waehler
-------------------------------
Birne            Peter
Apfel            Monika
Birne            Petra
Apfel            Peter
Erdbeere      Monika

Jetzt interessiert mich nicht mehr, wer für was, sondern wieviele Personen für was gestimmt haben.
Das erreiche ich durch das folgende select-Statement:

select Obst, count(*) as Anzahl from table group by Obst order by Anzahl desc, Obst

dadurch ensteht die folhgende Ausgabe:

Obst          Anzahl
----------------------------
Apfel             2
Birne             2
Erdbeere        1

Soweit so gut, aber jetzt möchte ich die Anzahl nicht als Zahlen sonder in Prozent ausgegeben haben, so daß das Ergebnis folgendermaßen aussehen würde:

Obst          Prozent
-----------------------------
Apfel            40
Birne            40
Erdbeere       20

Wer weiß, wie ich die select-Anweisung verändern muß, damit diese Ausgabe herauskommt?
Wenn's geht in MySQL oder Oracle.

Danke im Voraus

Beate Mielke

  1. Hallo Beate,

    Jetzt interessiert mich nicht mehr, wer für was, sondern wieviele Personen für was gestimmt haben.
    Das erreiche ich durch das folgende select-Statement:

    select Obst, count(*) as Anzahl from table group by Obst order by Anzahl desc, Obst

    dadurch ensteht die folhgende Ausgabe:

    Obst          Anzahl

    Apfel             2
    Birne             2
    Erdbeere        1

    Soweit so gut, aber jetzt möchte ich die Anzahl nicht als Zahlen sonder in Prozent ausgegeben haben, so daß das Ergebnis folgendermaßen aussehen würde:

    Obst          Prozent

    Apfel            40
    Birne            40
    Erdbeere       20

    Wer weiß, wie ich die select-Anweisung verändern muß, damit diese Ausgabe herauskommt?
    Wenn's geht in MySQL oder Oracle.

    Wenn dir eine Oracle Datenbank zur Verfuegung steht, kannst du dir eine kleine PL/SQL Funktion schreiben:

    Create Or Replace PACKAGE math is
      FUNCTION Rowcount Return NUMBER;
      Pragma Restrict_References(Rowcount, WNDS, WNPS, RNPS);
    End  math;
    /
    Create or Replace PACKAGE BODY math is
      FUNCTION Rowcount Return NUMBER is anzahl INTEGER;
      Begin
        SELECT count(*) INTO anzahl FROM table;
        Return anzahl;
      End Rowcount;
    End math;
    /

    Die Funktion Rowcount wird damit definiert und dauerhaft im Package math in der Datenbank unter deiner Userid abgelegt.
    math.Rowcount liefert die Anzahl der Saetze in der Tabelle table zurueck.
    Das gewuenschte Ergebnis erhalst du dann mit:

    SELECT Obst, Count(*)*100 /math.Rowcount as Prozent
    FROM table
    GROUP BY obst

    Ich weiss nicht, ob MySQL auch Prozeduren erlaubt. Falls nicht, kannst du dir mit einer Hilfstabelle behelfen:

    CREATE table temp (anzahl integer);

    1. Schritt:
    DELETE FROM temp;

    INSERT INTO temp
    SELECT count(*) FROM table;

    2. Schritt:

    SELECT a.Obst, Count(a.*)*100/b.anzahl
    FROM table a, temp b
    GROUP BY a.Obst

    Viele Gruesse
      Kess

    1. Hallo Beate,
      Ich weiss nicht, ob MySQL auch Prozeduren erlaubt. Falls nicht, kannst du dir mit einer Hilfstabelle behelfen:

      »»  ...

      1. Schritt:

      SELECT a.Obst, Count(a.*)*100/b.anzahl
      FROM table a, temp b
      GROUP BY a.Obst

      Sorry, es muß natuerlich heissen:

      SELECT a.Obst, Count(*)*100/b.anzahl
      FROM table a, temp b
      GROUP BY a.Obst, b.anzahl

      Viele Gruesse
        Kess

      1. Hallo Kess,

        SELECT a.Obst, Count(*)*100/b.anzahl
        FROM table a, temp b
        GROUP BY a.Obst, b.anzahl

        Dies und der Rest - es funktioniert einwandfrei.

        Bei mir sieht das jetzt so aus:

        Table1 = die urspruengliche Tabelle
        Table2 = die temporaere Tabelle

        Create table Table2 (integer Anzahl);
        delete from Table2;
        insert into Table2 select count(*) from Table1;
        select a.Spalte1, count(*)*100/b.Anzahl as prozent from Table1 a, Table2 b group by a.Spalte1, b.Anzahl order by prozent desc, Spalte1;

        Zwei Fragen noch:

        1. Die Prozentausgaben werden übrigens mit zwei Nachkommastellen angegeben. Weißt Du, ob das immer so ausgegeben wird, oder kann man das variable halten?
        2. Denkst Du, dass die man die Zeilen fuer MySQL und Oracle identisch halten kann? Ich brauche naemlich beides.

        Jedenfalls herzlichen Dank, das war einfach genial (nachdem ich schon zwei Tage herumgebastelt habe).

        Viele Grüße

        Beate Mielke

        1. Hallo Beate,

          Die MySQL-Loesung funktioniert natuerlich auch mit Oracle.
          Ich persoenlich finde eine Funktion, wie man sie mit PL/SQL bei Oracle realisieren kann einfach eleganter. Aber nicht alle Datenbanken bieten diese Funktionalitaet an.  Darum hatte ich auch die zweite Variante gepostet. Die lauft mit jeder Datenbank, die Standard SQL unterstuetzt.

          Table1 = die urspruengliche Tabelle
          Table2 = die temporaere Tabelle

          Create table Table2 (integer Anzahl);
          delete from Table2;
          insert into Table2 select count(*) from Table1;
          select a.Spalte1, count(*)*100/b.Anzahl as prozent from Table1 a, Table2 b group by a.Spalte1, b.Anzahl order by prozent desc, Spalte1;

          Create Table2 brauchst du natuerlich nur ein einziges mal auszufuehren. Wenn die Tabelle einmal existiert bleibt sie auch erhalten.
          Delete from Table2 sorgt dafür, daß bei wiederholter Ausfuehrung kein alter Mist von vorherigen Abfragen in Table2 stehen bleibt.
          Die eigentliche Verarbeitung erledigen das Insert- und das Select-Statement.

          1. Die Prozentausgaben werden übrigens mit zwei Nachkommastellen angegeben. Weißt Du, ob das immer so ausgegeben wird, oder kann man das variable halten?

          Dazu kannst du die Funktion ROUND(x,n) benutzten. Dabei ist x die Zahl, die gerundet werden soll und n die Zahl der Nachkommastellen, auf die gerundet werden soll. Gerundet wird kaufmaennisch.
          ROUND(count(*)*100/b.Anzahl, 3) gibt die Prozentzahlen mit 3 Nachkommastellen aus.

          1. Denkst Du, dass die man die Zeilen fuer MySQL und Oracle identisch halten kann? Ich brauche naemlich beides.

          MySQL hat natürlich nicht den gleichen Funktionsumfang wie Oracle. Solange du dich aber auf Standard SQL beschraenkst und dabei beachtest, was MySQL noch nicht beherrscht, kannst du die Zeilen identisch halten. Das ist der Sinn der Standardisierung. SQL sollte eben jede Datenbank anstandslos ausfuehren. :-)
          Zu MySQL gibt es auch gute Quellen im Internet. Schau mal im Linkverzeichns unter Datenbankanbindung (http://www.teamone.de/selfaktuell/links/datenbank_dokus.htm). Wenn du denn Quellen folgst, findest du unter http://web.mysql.com/Manual_chapter/manual_Compatibility.html#Missing_functions Angaben über nich nicht in MySQL realisierte Funktionen.

          Jedenfalls herzlichen Dank, das war einfach genial (nachdem ich schon zwei Tage herumgebastelt habe).

          Wirklich gern geschehen. :-)

          Viele Gruesse
            Kess