sqlmysql

Is there anyway to add multi "IF" condition in MySQL?


I want to query something from my database and DB has multiple answers for various scenarios.

Question: find the type of triangle based on the length of sides. DB has these columns with Numeric datatype:

Side A Side B Side C
20 20 23
20 20 20

My dummy MySQL code:

SELECT IF( A = B = C, 'Equilateral', NULL) OR IF( A = B != C OR B = C != A OR A = C != B, 'Isosceles', NULL) OR IF( A != B  AND B != C AND A != C , 'Scalene', NULL) OR IF( A + B < C OR A + C < B OR C + B < A , 'Not A Triangle', NULL) FROM TRIANGLES;

I get this unexpected output:

NULL

NULL

NULL

I expect the query code to give me only one correct response for each row. I don't know how to do this without using other programming languages.


Solution

  • You won't get an if in pure SQL (which is not a procedural language), unless with RDBMS-specific extensions (SQL extensions, like MySQL's IF, or procedural extensions, like in PL/pgSQL),
    but you will get a CASE WHEN … THEN … ELSE … END
    (equivalent of a switch(…) { case …: …; break; } in C-like languages),
    which more nicely fits your need, and improves readability of your expression (… and thus debugging, as you will see in the example).

    It works by returning the expression that follows the first matching WHEN (see Optimization below for the implications).

    So your example could be written:

    SELECT
        CASE
            WHEN A = B AND B = C THEN 'Equilateral'
            WHEN A = B OR B = C OR A = C THEN, 'Isosceles' -- Note that no need to write != C (after A = B), as the Equilateral case ate the A = B = C case, we are guaranteed to only have the != C case left in this WHEN.
            ELSE 'Scalene' -- Same here: the two preceding cases ate all cases having an equality.
            -- And so here, wanting to add another ELSE makes us understand the logic error, as the test for 'Not a Triangle' should have been place before all other ones or at least the Isosceles.
        END
    FROM TRIANGLES;
    

    Optimization

    Similarly to the switch and the if too in other languages,
    CASE WHEN allows the RDBMS to optimize the execution by short-circuiting the later WHENs as soon as a former WHEN succeeds.

    This is not guaranteed,\but you won't loose anything by always starting with the simplest tests or more common cases, for example in a post office:

    CASE
        WHEN dest_zipcode = here_zipcode THEN 'local' -- This one is more common than the next one
        WHEN dest_country <> 'USA' THEN 'foreign' -- … but this one is easier to compute than the next one.
        WHEN EXISTS (SELECT 1 FROM us_cities WHERE ZIPCODE = dest_zipcode) THEN 'usa'
        ELSE 'unknown'
    END AS distribution