Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Sortierung der Ausgabe

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Sortierung der Ausgabe

    Ich lasse Werte aus einer Tabelle mit phpplot als Balkendiagramm anzeigen.
    PHP-Code:
    $aw $pdo->query("SELECT SUM(aw_wert) AS aw, ma_id
                       FROM ma_statistik
                       WHERE YEAR(datum)= 2015
                       GROUP BY ma_id, aw_id"
    ); 
    Die Ausgabe ist dann bspw.:
    aw | ma_id
    5428,48 | 43
    6403,45 | 43
    181,74 | 44
    456,14 | 44
    2619,25 | 45
    3601,72 | 45

    Nun werden die zusammengehörigen Werte (ma_id) auch schön gruppiert.
    Was mir jetzt noch fehlt, ist die Sortierung nach ma_id - Summen.
    Es müsste also eigentlich so aussehen:

    aw | ma_id
    5428,48 | 43
    6403,45 | 43
    2619,25 | 45
    3601,72 | 45
    181,74 | 44
    456,14 | 44

    Die zusamefassten Werte von ma_id 43 (5428,48+6403,45) wären also das eigentliche Sortierkriterium.
    Mit ORDER BY komme ich nicht weiter. Wie kann man das machen?

  • #2
    Du kannst vermutlich die zuletzt gezeigte Tabelle als Sub-Query nehmen und die erste Query dranjoinen.

    Edit: Ups, die zeigst du gar nicht. Ich meine diese (nur nach ma_id gruppiert und nach SUM(aw) sortiert):

    Code:
    SUM(aw)  | ma_id
    ---------+------
    11831.93 | 43
    6220.97  | 45
    637.88   | 44

    Kommentar


    • #3
      Zitat von tamper Beitrag anzeigen
      Mit ORDER BY komme ich nicht weiter. Wie kann man das machen?
      Bitter erläutern...

      ORDER BY ist genau das, was du suchst - wo hakt es?
      Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

      Kommentar


      • #4
        Siehe mein Edit. Geht wohl darum, nach SUM(aw) GROUP BY (ma_id) zu sortieren, aber letztlich das SUM(aw) für jede ma_id noch mal unterteilt nach aw_id zu liefern.

        Kommentar


        • #5
          Zitat von tamper Beitrag anzeigen
          Die zusamefassten Werte von ma_id 43 (5428,48+6403,45) wären also das eigentliche Sortierkriterium.
          Mit ORDER BY komme ich nicht weiter. Wie kann man das machen?
          Dazu müsstest du ein Subquery machen der dir für die entsprechenden ma_ids die Summe bestimmt und danach kannst du dann sortieren.


          PHP-Code:
          SELECT
          ...
          FROM
           ma_statistik INNER JOIN
           
          (
           
          SELECT SUM(aw_wert) AS summa_id
                             FROM ma_statistik
                             WHERE YEAR
          (datum)= 2015
                             GROUP BY ma_id
          ) AS temp ON (...)
          ORDER BY
          temp
          .sum,  ma_statistik.ma_id 

          Kommentar


          • #6
            Zitat von erc Beitrag anzeigen
            Dazu müsstest du ein Subquery machen der dir für die entsprechenden ma_ids die Summe bestimmt und danach kannst du dann sortieren.
            Das scheint wohl des Rätsels Lösung, allerdings muß ich mir erstmal ansehen wie das funktioniert. Sieht für'n Anfänger nicht leicht aus. Vielen Dank vorerst!

            Kommentar


            • #7
              Leider erschließt sich mir nicht, wie man eine solche Unterabfrage sinnvoll in die bestehende einbaut wie mermshaus im #2 gezeigt hat.
              Klar, die Tablle ist mein Sortierkriterium.
              Code:
              SUM(aw)  | ma_id
              ---------+------
              11831.93 | 43
              6220.97  | 45
              637.88   | 44
              Aber wie bekomme ich das RICHTIG zusammen (ohne Syntaxfehler zu produzieren)?
              Abfrage für die Ausgabe:
              Code:
              SELECT SUM(aw_wert) AS aw, ma_id
                                 FROM ma_statistik
                                 WHERE YEAR(datum)= 2015
                                 GROUP BY ma_id, aw_id
              Sortierkriterium
              Code:
              SELECT SUM(aw_wert) AS aw, ma_id
                                 FROM ma_statistik
                                 WHERE YEAR(datum)= 2015
                                 GROUP BY ma_id
              Und warum der Join? Das verstehe ich auch nicht.
              Bei Peter Kropff und in der SQL Doku ist es leider wenig Anfängerfreundlich erklärt wie man Unterabfragen richtig einbaut.
              Beispiele dafür habe ich nur in der und ähnlicher Art gefunden, die ich für mein Anliegen nicht nutzen kann.
              Code:
              SELECT 
              AVG(tabelle.anzahlKundenProOrt) 
              FROM 
              (SELECT 
              ort.name, COUNT(*) as anzahlKundenProOrt 
              FROM 
              kunde, ort 
              WHERE 
              ort.postleitzahl = kunde.ort_postleitzahl 
              GROUP BY ort.name 
              HAVING anzahlKundenProOrt > 2) AS tabelle;

              Kommentar


              • #8
                Ein Subquery im FROM verhält sich wie eine Tabelle. Du musst aus meinem Beispiel eigentlich nur die FROM Klausel übernehmen, die JOIN Bedingung ausfüllen (das ...) und die ORDER BY Klausel übernehmen.

                Kommentar


                • #9
                  Zitat von erc Beitrag anzeigen
                  Ein Subquery im FROM verhält sich wie eine Tabelle. Du musst aus meinem Beispiel eigentlich nur die FROM Klausel übernehmen, die JOIN Bedingung ausfüllen (das ...) und die ORDER BY Klausel übernehmen.
                  PHP-Code:
                  SELECT
                  ... // ???
                  FROM
                   ma_statistik INNER JOIN
                   
                  (
                   
                  SELECT SUM(aw_wert) AS summa_id
                                     FROM ma_statistik
                                     WHERE YEAR
                  (datum)= 2015
                                     GROUP BY ma_id
                  ) AS temp ON (...) // ???
                  ORDER BY
                  temp
                  .sum,  ma_statistik.ma_id 
                  Es ist mir schon unangenehm das ich das nicht verstehe.
                  --- Eine UNTERABFRAGE im VOM/AUS verhält sich wie eine Tabelle???
                  Heißt das, die ersten drei Pünktchen sind gar nicht relevant?

                  AS temp ON (...) WAS? Woran soll ich das binden, und warum?
                  Tut mir leid, ich versteh den Zusammenhang nicht.

                  Bevor ich diese Fragen nicht klären kann sind die Fehlermeldungen natürlich immer Syntax bezogen, das hat wenig Sinn.

                  Wie kann man das vereinfachen um es besser zu verstehen?
                  PHP-Code:
                  SELECT
                  SUM
                  (aw_wert) AS summa_id
                  FROM
                  ma_statistik 
                  INNER JOIN 
                  (
                   
                  SELECT SUM(aw_wert) AS summa_id
                   FROM ma_statistik
                   WHERE YEAR
                  (datum)= 2015
                   GROUP BY ma_id

                  AS 
                  temp ON (...) // ???
                  ORDER BY
                  temp
                  .sum,  ma_statistik.ma_id 
                  Ich weiß wirklich nicht, wie ich das zusammensetzen soll...

                  Kommentar


                  • #10
                    Meine Variante wäre so:

                    Code:
                    SELECT
                            SUM(`outer`.aw_wert) AS aw,
                            `outer`.ma_id        AS ma_id
                    FROM
                        (
                            SELECT
                                    SUM(aw_wert) AS aw,
                                    ma_id
                            FROM
                                    ma_statistik
                            WHERE
                                    YEAR(datum) = 2015
                            GROUP BY
                                    ma_id
                        ) AS `inner`
                    INNER JOIN
                            ma_statistik AS `outer`
                        ON
                            `inner`.ma_id = `outer`.ma_id
                    WHERE
                            YEAR(datum) = 2015
                    GROUP BY
                            `outer`.ma_id,
                            `outer`.aw_id
                    ORDER BY
                            `inner`.aw DESC,
                            SUM(`outer`.aw_wert) ASC
                    PS: Es ist bei so was immer gut, Testdaten bereitzustellen.

                    Kommentar


                    • #11
                      Hallo mermshaus,

                      diese Variante macht genau das was sie soll, allerdings verstehe ich kaum was Du da gebastelt hast.
                      Das könnte ebenso compiliert vorliegen...
                      Wieso schüttelst Du so etwas einfach aus dem Ärmel? Ohne Testdaten
                      Unglaublich!

                      Ich versuche es mal:
                      Code:
                      // Ist das 'outer' hier nötig (nur eine Tabelle)?
                      SELECT SUM(`outer`.aw_wert) AS aw, `outer`.ma_id AS ma_id
                      
                      // Das ist wohl was erc meinte: Eine Unterabfrage im FROM verhält sich wie eine Tabelle
                      FROM (
                       SELECT SUM(aw_wert) AS aw, ma_id
                       FROM ma_statistik
                       WHERE YEAR(datum) = 2015
                       GROUP BY ma_id
                      ) 
                      
                      // hier hört es für mich auf verständlich zu sein :-(
                      AS `inner` INNER JOIN ma_statistik AS `outer` ON `inner`.ma_id = `outer`.ma_id
                      WHERE YEAR(datum) = 2015
                      GROUP BY `outer`.ma_id, `outer`.aw_id
                      ORDER BY `inner`.aw DESC, SUM(`outer`.aw_wert) ASC

                      Kommentar


                      • #12
                        Wieso schüttelst Du so etwas einfach aus dem Ärmel? Ohne Testdaten
                        Nicht so ganz…

                        Code:
                        CREATE TABLE IF NOT EXISTS `ma_statistik` (
                          `aw_wert` decimal(10,2) NOT NULL,
                          `ma_id` int(11) NOT NULL,
                          `aw_id` int(11) NOT NULL,
                          `datum` datetime NOT NULL
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
                        
                        INSERT INTO `ma_statistik` (`aw_wert`, `ma_id`, `aw_id`, `datum`) VALUES
                        (5328.48, 43, 1, '2015-02-04 23:31:00'),
                        (100.00, 43, 1, '2015-02-04 23:31:00'),
                        (6303.45, 43, 2, '2015-02-04 23:31:00'),
                        (100.00, 43, 2, '2015-02-04 23:31:00'),
                        (81.74, 44, 3, '2015-02-04 23:31:00'),
                        (100.00, 44, 3, '2015-02-04 23:31:00'),
                        (356.14, 44, 4, '2015-02-04 23:31:00'),
                        (100.00, 44, 4, '2015-02-04 23:31:00'),
                        (2519.25, 45, 5, '2015-02-04 23:31:00'),
                        (100.00, 45, 5, '2015-02-04 23:31:00'),
                        (3501.72, 45, 6, '2015-02-04 23:31:00'),
                        (100.00, 45, 6, '2015-02-04 23:31:00');
                        Ich bin auch nicht gut genug in so was, um etwa den Code, den ihr schon hattet, schnell zu erweitern. Es ist einfacher für mich, dann eine ganz ähnliche Query zu schreiben, nur eben mit „meiner“ Logik und meinen Bezeichnern im Kopf.

                        // Ist das 'outer' hier nötig (nur eine Tabelle)?
                        SELECT SUM(`outer`.aw_wert) AS aw, `outer`.ma_id AS ma_id
                        Man kann es offenbar/vermutlich zum Beispiel auch so schreiben:

                        Code:
                        SELECT
                                SUM(aw_wert) AS aw,
                                ma_id
                        FROM
                            (
                                SELECT
                                        SUM(aw_wert) AS inner_sum,
                                        ma_id AS inner_id
                                FROM
                                        ma_statistik
                                WHERE
                                        YEAR(datum) = 2015
                                GROUP BY
                                        ma_id
                            ) AS `unused`
                        INNER JOIN
                                ma_statistik
                            ON
                                inner_id = ma_id
                        WHERE
                                YEAR(datum) = 2015
                        GROUP BY
                                ma_id,
                                aw_id
                        ORDER BY
                                inner_sum DESC,
                                SUM(aw_wert) ASC
                        Das ist wohl was erc meinte: Eine Unterabfrage im FROM verhält sich wie eine Tabelle
                        Ja.

                        INNER JOIN ma_statistik AS `outer` ON `inner`.ma_id = `outer`.ma_id
                        Zu Joins:

                        - http://blog.codinghorror.com/a-visua...-of-sql-joins/
                        - SQL und relationale Algebra

                        WHERE YEAR(datum) = 2015
                        Ich weiß nicht, ob es notwendig ist, das „außen“ auch noch mal im WHERE zu haben. (Da fehlt konsequenterweise ein `outer` vor dem datum. Das dürfte aber keinen Effekt haben.)

                        GROUP BY `outer`.ma_id, `outer`.aw_id
                        Das ist wie in deiner Ausgangsabfrage.

                        ORDER BY `inner`.aw DESC, SUM(`outer`.aw_wert) ASC
                        Und das sagt dann eben: „Sortiere nach der höchsten Gesamtsumme nach ma_id gruppiert (dafür wird die Subquery benötigt) und in dieser Sortierung noch mal absteigend nach den jeweiligen Teilsummen nach aw_id gruppiert.“

                        Das wird vielleicht deutlicher, wenn du dir im äußeren SELECT noch einige andere Spalten ausgeben lässt.

                        Code:
                        mysql> SELECT
                            ->         SUM(`outer`.aw_wert) AS aw,
                            ->         `outer`.ma_id        AS ma_id,
                            ->         `inner`.aw           AS inner_sum,
                            ->         `outer`.aw_id        AS aw_id
                            -> FROM
                            ->     (
                            ->         SELECT
                            ->                 SUM(aw_wert) AS aw,
                            ->                 ma_id
                            ->         FROM
                            ->                 ma_statistik
                            ->         WHERE
                            ->                 YEAR(datum) = 2015
                            ->         GROUP BY
                            ->                 ma_id
                            ->     ) AS `inner`
                            -> INNER JOIN
                            ->         ma_statistik AS `outer`
                            ->     ON
                            ->         `inner`.ma_id = `outer`.ma_id
                            -> WHERE
                            ->         YEAR(datum) = 2015
                            -> GROUP BY
                            ->         `outer`.ma_id,
                            ->         `outer`.aw_id
                            -> ORDER BY
                            ->         `inner`.aw DESC,
                            ->         SUM(`outer`.aw_wert) ASC;
                        +---------+-------+-----------+-------+
                        | aw      | ma_id | inner_sum | aw_id |
                        +---------+-------+-----------+-------+
                        | 5428.48 |    43 |  11831.93 |     1 |
                        | 6403.45 |    43 |  11831.93 |     2 |
                        | 2619.25 |    45 |   6220.97 |     5 |
                        | 3601.72 |    45 |   6220.97 |     6 |
                        |  181.74 |    44 |    637.88 |     3 |
                        |  456.14 |    44 |    637.88 |     4 |
                        +---------+-------+-----------+-------+
                        6 rows in set (0.00 sec)

                        Kommentar


                        • #13
                          Zitat von tamper Beitrag anzeigen
                          diese Variante macht genau das was sie soll, allerdings verstehe ich kaum was Du da gebastelt hast.
                          Deswegen hab ich kein fertigen Query gepostet. Du hättest es verstehen müssen um den Query zusammen zusetzen. Ich versuchs nochmal kurz zu erklären:
                          Um etwas zu sortieren brauchst du ein Wert nach dem du sortieren willst. Den Wert nach dem du sortieren willst ist aber in deinen Rohdaten nicht verfügbar und muss berechnet werden (summe pro ma_id). Jetzt könntest du dafür eine extra Tabelle anlegen in der für jede ma_id die Summe speicherst. Nennen wir die Tabelle z.B. ma_summe und die Spalten ma_id umd summe. Auf diese Tabelle kannst du dann mit der ma_id joinen und nach deren Summe sortieren.

                          PHP-Code:
                          SELECT
                          ...
                          FROM
                            ma_statistik INNER JOIN
                            ma_summe ON 
                          (ma_statistik.ma_id ma_summe.ma_id)
                          ORDER BY
                            ma_summe
                          .summe 
                          Ein extra Tabelle ist aber unpraktisch, irgendwie muss sie aktuell gehalten werden. Das ist ein Aufwand der sich nur unter bestimmten Bedingungen lohnt. Also verzichten wir auf diese Tabelle und erzeugen uns diese Tabelle "virtuelle" mit einem Subquery.

                          PHP-Code:
                          SELECT
                          ...
                          FROM
                            ma_statistik INNER JOIN
                            
                          (SELECT ma_idSUM(aw_wert) AS summe FROM ...) AS ma_summe ON (ma_statistik.ma_id ma_summe.ma_id)
                          ORDER BY
                            ma_summe
                          .summe 
                          Zitat von mermshaus
                          Ich weiß nicht, ob es notwendig ist, das „außen“ auch noch mal im WHERE zu haben. (Da fehlt konsequenterweise ein `outer` vor dem datum. Das dürfte aber keinen Effekt haben.)
                          Die begrenzung des Datums ist an beiden Stellen zwingend erforderlich. Die Summen werden ansonsten über verschiedene Zeiträume gebildet. Das würde nur unter bestimmten Bedingungen sinn machen.

                          Kommentar


                          • #14
                            Zitat von erc Beitrag anzeigen
                            Jetzt könntest du dafür eine extra Tabelle anlegen in der für jede ma_id die Summe speicherst. Nennen wir die Tabelle z.B. ma_summe und die Spalten ma_id umd summe. Auf diese Tabelle kannst du dann mit der ma_id joinen und nach deren Summe sortieren.
                            Das ist die Erklärung, die es für mich verständlicher macht.
                            Abfragen zu verbinden ist auch nicht ganz einfach, aber damit habe ich ein bischen Erfahrung.
                            Als Denkhilfe an dieser Stelle sich eine andere Tabelle vorzustellen macht es verständlicher und einfacher die Abfrage zu bauen.

                            Vielen Dank Euch beiden!

                            Kommentar

                            Lädt...
                            X