Sigmar: mysql: Wie frage ich die Punkte ab?

Hallo Forum,

meine DB ist in etwa so aufgebaut:

Tabelle:

ID    Art        Multi       User         Punkte
---+-----------+----------+-------------+----------+
1  + F         + ja       + Pe          + 50       +
---+-----------+----------+-------------+----------+
2  + A         + 150      + Pe,Fr,Tg    + 150      +
---+-----------+----------+-------------+----------+
3  + F         + 150      + Pe,Fr,Tg    + 500      +
---+-----------+----------+-------------+----------+
4  + T         + 200      + Pe,Fr       + 20       +
---+-----------+----------+-------------+----------+

Es geht darum, für eine bestimmte ID die Gesamtpunkte zu errechnen.

Bedingung 1:

Hierbei soll beachtet werden, dass der Multi entweder eine Zahl oder die Worte "ja" und "nein" oder NULL beinhalten kann. "ja" wäre mit 1 gleichzusetzen, "nein" mit 0, NULL mit 1.

Bedingung 2:

Und es soll beachtet werden, dass bei mehreren Usern die Punkte dann mit der Anzahl der User (hier durch Komma getrennt) multipliziert werden soll, falls die Art des Spiels "A" entspricht.

Ich habe bisher folgende Query:

SELECT sum(Punkte* (CASE WHEN Multi = 'ja' THEN 1 WHEN Multi = '' THEN 1 WHEN Multi = '100' THEN 1 WHEN Multi = '150' THEN 1.50 WHEN Multi = '200' THEN 2.00 WHEN Multi = 'nein' THEN 0 WHEN ISNULL(Multi) THEN 1 END) ) AS points FROM Tabelle WHERE ID=2

Ich schaffe es aber nicht, Bedingung einzubauen.

Könnt Ihr mir dabei bitte helfen?

Grüße, Sigmar

  1. Hallo Sigmar,

    meine DB ist in etwa so aufgebaut:

    ID    Art        Multi       User         Punkte
    ---+-----------+----------+-------------+----------+
    1  + F         + ja       + Pe          + 50       +
    2  + A         + 150      + Pe,Fr,Tg    + 150      +
    3  + F         + 150      + Pe,Fr,Tg    + 500      +
    4  + T         + 200      + Pe,Fr       + 20       +

    Dein erster Schritt sollte es sein, Deine Tabellen zu normalisieren.
    Danach dürfte Dein Problem trivial zu lösen sein. Es ist fast nie eine gute Idee, in einem Datenbankfeld nicht atomare Daten abzulegen.

    Freundliche Grüße

    Vinzenz

    1. Dein erster Schritt sollte es sein, Deine Tabellen zu normalisieren.

      Hi Vinzenz,

      zu spät. Ich muss nun leider hiermit Vorlieb nehmen :-(
      Ist auch nicht weiter schlimm, weil ich selten etwas ändern muss.
      Aber grad jetzt hast Du natürlich recht, es wäre viel einfacher in einer normalisierten Tabelle.

      Ich bin jetzt in etwa so weit:

      SELECT sum(Punkte* (CASE WHEN Multi = 'ja' THEN 1 WHEN Multi = '' THEN 1 WHEN Multi = '100' THEN 1 WHEN Multi = '150' THEN 1.50 WHEN Multi = '200' THEN 2.00 WHEN Multi = 'nein' THEN 0 WHEN ISNULL(Multi) THEN 1 END) * (CASE WHEN Art = "F" THEN 1 WHEN ART = "T" THEN 1 WHEN Art = "A" THEN (LENGHT(User) - LENGHT(REPLACE(User, ',', ''))+1) END ) ) AS points FROM Tabelle WHERE ID=2

      Aber so richtig funktionieren tuts noch nicht, denn ich bekomme zur Antwort:

       MySQL meldet:

      FUNCTION DBuu77754.LENGHT does not exist

       :-(

      Meine mySql-Version: MySQL 5.0.91

      Gruß, Sigmar

      1. Hi,

        FUNCTION DBuu77754.LENGHT does not exist

        Lerne, wie man Länge auf Englisch schreibt.

        cu,
        Andreas

        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.

        -- Warum nennt sich Andreas hier MudGuard?
        O o ostern ...
      2. Hi,

        MySQL meldet:

        FUNCTION DBuu77754.LENGHT does not exist

        Typo, die Funktion heißt LENGTH.

        Bis die Tage,
        Matti

        -- Webapplikationen in C++ entwickeln
  2. moin

    meine DB ist in etwa so aufgebaut:

    dein deisgn ist für das, was du machen willst nicht optimal aufgebaut., deswegen bekommst du jetzt auch schwierigkeiten bei der auswahl und man muss anfangen zu "tricksen". zum glück ist SQL recht mächtig und es findet sich fast immer  eine lösung.

    SELECT sum(Punkte* (CASE WHEN Multi = 'ja' THEN 1 WHEN Multi = '' THEN 1 WHEN Multi = '100' THEN 1 WHEN Multi = '150' THEN 1.50 WHEN Multi = '200' THEN 2.00 WHEN Multi = 'nein' THEN 0 WHEN ISNULL(Multi) THEN 1 END) ) AS points FROM Tabelle WHERE ID=2

    erstens brauchst du keine aggregatfunktion, du behandelst eh nur einen datensatz. zweitens ist deine case logik meiner meinung nach nicht richtig implementiert. es fehlt noch die multiplikation, es fehlt deine 2. Bedingung. afür würde ich den wert noch mal mit einer zweiten case anweisung muplizieren, sprich wenn die art des spiels A entspricht, dann multiplizere mit anzahl der user, sonst 1

    Anzahl der user = LENGTH(USER) - LENGTH(REPLACE(USER, ',', '')) + 1

    PS: kann sein, dass die funktionen bei mysql in wenig anders heißen, z.b. nicht LENGTH, sondern LEN, musst du halt schauen

    Ilja

    1. moin

      afür würde ich den wert noch mal mit einer zweiten case anweisung muplizieren, sprich wenn die art des spiels A entspricht, dann multiplizere mit anzahl der user, sonst 1

      Anzahl der user = LENGTH(USER) - LENGTH(REPLACE(USER, ',', '')) + 1

      PS: kann sein, dass die funktionen bei mysql in wenig anders heißen, z.b. nicht LENGTH, sondern LEN, musst du halt schauen

      Ilja

      Hallo Ilja,

      wir haben in etwa zeitgleich gepostet, daher habe ich meine Antwort unter Vinzenz' Post geschrieben, sie würde aber auch gut hierher passen.

      Danke für den Tip, ich bin fast zeitgleich darauf gestoßen.

      Aber genauso klappt es:

      SELECT sum(Punkte* (CASE WHEN Multi = 'ja' THEN 1 WHEN Multi = '' THEN 1 WHEN Multi = '100' THEN 1 WHEN Multi = '150' THEN 1.50 WHEN Multi = '200' THEN 2.00 WHEN Multi = 'nein' THEN 0 WHEN ISNULL(Multi) THEN 1 END) * (CASE WHEN Art = "F" THEN 1 WHEN ART = "T" THEN 1 WHEN Art = "A" THEN (LENGTH(User) - LENGTH(REPLACE(User, ',', ''))+1) END ) ) AS points FROM Tabelle WHERE ID=2

      Gruß, Sigmar

      1. moin,

        ich würde mit einem ELSE fall im CASE arbeiten, und wenn du nur damit die Fehler abfängts.

        Ilja