Pit: mysql: Case/When Abfrage liefert unerwartetes Ergebnis

Hallo,

eine Tabelle:

mysql> select * FROM phppos_items_taxes;
+---------+-----------+---------+------------+
| item_id | name      | percent | cumulative |
+---------+-----------+---------+------------+
|       1 | Tax 1     |    8.00 |          0 |
|       1 | Tax 2     |   10.00 |          1 |
|       3 | Sales Tax |    8.00 |          0 |
|       4 | Tax 1     |   20.00 |          0 |
|       4 | Tax 2     |   20.00 |          0 |
+---------+-----------+---------+------------+

liefert zur Query:

SELECT 
    SUM(
        CASE 
           WHEN cumulative = 1 THEN percent
           WHEN cumulative = '' THEN 1000
           ELSE 0 
        END) 
FROM phppos_items_taxes;

das Ergebnis:

4010

Ich hatte 10 erwartet.

Kann mir jemand erklären, warum mysql das hier macht? Zusatz: Die Spalte "cumulative" ist vom Typ int.

Gruß, Pit

  1. Tach!

    Kann mir jemand erklären, warum mysql das hier macht? Zusatz: Die Spalte "cumulative" ist vom Typ int.

    Die eigentliche Frage ist, warum du diese Spalte dann mit einem Leerstring zu vergleichen versuchst. MySQL versucht jedenfalls die beiden unterschiedlichen Typen zu vergleichen und konvertiert den Leerstring in eine Zahl: 0.

    dedlfix.

    1. Hallo dedlfix,

      Die eigentliche Frage ist, warum du diese Spalte dann mit einem Leerstring zu vergleichen versuchst.

      Deine erste Frage ist natürlich berechtigt. Mich interessiert es einfach, deshalb frage ich nach. Natürlich versuche ich das in der Praxis zu vermeiden.

      MySQL versucht jedenfalls die beiden unterschiedlichen Typen zu vergleichen und konvertiert den Leerstring in eine Zahl: 0.

      Müßte aber nicht dann eine Abfrage ala:

      SELECT 
          SUM(
              CASE 
                 WHEN cumulative = 1 THEN percent
                 WHEN cumulative = 'auzzuuisdfhiwq' THEN 1000
                 ELSE 0 
              END) 
      FROM phppos_items_taxes;
      

      10 ergeben?

      Das Ergebnis ist aber wieder 4010.

      Gruß, Pit

      1. Tach!

        Müßte aber nicht dann eine Abfrage ala:

        SELECT 
            SUM(
                CASE 
                   WHEN cumulative = 1 THEN percent
                   WHEN cumulative = 'auzzuuisdfhiwq' THEN 1000
                   ELSE 0 
                END) 
        FROM phppos_items_taxes;
        

        10 ergeben?

        Die eigentliche Frage ist, wie unterschiedliche Typen miteinander verglichen werden, beziehungsweise wie Strings in Zahlen konvertiert werden. Dein String ist jedenfalls keine Zahl und bei der Konvertierung kommt 0 raus.

        dedlfix.

      2. Das ist zu erwarten.

        
        > select "uzzuuisdfhiwq" = 0;
        
        +---------------------+
        | "uzzuuisdfhiwq" = 0 |
        +---------------------+
        |                   1 |
        +---------------------+
        1 row in set, 1 warning (0.00 sec)
        
        
        > select  0 = "uzzuuisdfhiwq";
        
        +---------------------+
        | 0 = "uzzuuisdfhiwq" |
        +---------------------+
        |                   1 |
        +---------------------+
        1 row in set, 1 warning (0.00 sec)
        
        1. 
          > select "uzzuuisdfhiwq" = CONVERT(0 using ASCII) ;
          
          +------------------------------------------+
          | "uzzuuisdfhiwq" = CONVERT(0 using ASCII) |
          +------------------------------------------+
          |                                        0 |
          +------------------------------------------+
          1 row in set (0.00 sec)
          
          
          > select "" = CONVERT(0 using ASCII);
          
          +-----------------------------+
          | "" = CONVERT(0 using ASCII) |
          +-----------------------------+
          |                           0 |
          +-----------------------------+
          1 row in set (0.00 sec)
          
          1. Hallo dedlfix, Hallo Ursus,

            ok, ich verstehe es.

            Jeglicher String wird also von mysql als 0 interpretiert, korrekt?

            Sowas in dieser Art hatte bei mir nämlich zu einem Fehler geführt, den ich mir nicht erklären konnte. Die Abfrage und der Vergleich eines String mit einer Integer-Spalte rührte daher, dass ich die Abfrage aus einer anderen Abfrage übernommen hatte. Die entsprechende Tabelle hatte aber eine varchar-Spalte…

            Danke für Eure Hilfe,

            Pit

            1. Jeglicher String wird also von mysql als 0 interpretiert, korrekt?

              Nein.

              
              > select 1 = "1abc";
              
              +------------+
              | 1 = "1abc" |
              +------------+
              |          1 |
              +------------+
              1 row in set, 1 warning (0.00 sec)
              
              
              > select 1 = "abc1";
              
              +------------+
              | 1 = "abc1" |
              +------------+
              |          0 |
              +------------+
              1 row in set, 1 warning (0.00 sec)
              

              Jeglicher String, der sich nicht als Zahl interpretieren lässt (konkret mit der Darstellung einer solchen beginnt) wird beim Vergleich mit einer Zahl zu 0 konvertiert.

  2. Kann mir jemand erklären, warum mysql das hier macht?

    Ich.

    
    > select "" = 0;
    
    +--------+
    | "" = 0 |
    +--------+
    |      1 |
    +--------+
    1 row in set, 1 warning (0.00 sec)
    
    
    > select 0 = "";
    
    +--------+
    | 0 = "" |
    +--------+
    |      1 |
    +--------+
    1 row in set, 1 warning (0.00 sec)