[mysql] How do I use properly CASE..WHEN in MySQL

Here is a demo query, notice it is very simple, Fetches only where base_price is 0, And still, it chooses the condition 3:

SELECT
   CASE course_enrollment_settings.base_price
    WHEN course_enrollment_settings.base_price = 0      THEN 1
    WHEN course_enrollment_settings.base_price<101      THEN 2
    WHEN course_enrollment_settings.base_price>100 AND   
                      course_enrollment_settings.base_price<201 THEN 3
        ELSE 6
   END AS 'calc_base_price',
   course_enrollment_settings.base_price
FROM
    course_enrollment_settings
WHERE course_enrollment_settings.base_price = 0

base_price is decimal(8,0)

When run this on my DB, I get:

3 0
3 0
3 0
3 0
3 0

This question is related to mysql sql conditional switch-statement case

The answer is


I think part of it is that you're stating the value you're selecting after CASE, and then using WHEN x = y syntax afterward, which is a combination of two different methods of using CASE. It should either be

CASE X
  WHEN a THEN ...
  WHEN b THEN ...

or

CASE
  WHEN x = a THEN ...
  WHEN x = b THEN ...

There are two variants of CASE, and you're not using the one that you think you are.

What you're doing

CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

Each condition is loosely equivalent to a if (case_value == when_value) (pseudo-code).

However, you've put an entire condition as when_value, leading to something like:

if (case_value == (case_value > 100))

Now, (case_value > 100) evaluates to FALSE, and is the only one of your conditions to do so. So, now you have:

if (case_value == FALSE)

FALSE converts to 0 and, through the resulting full expression if (case_value == 0) you can now see why the third condition fires.

What you're supposed to do

Drop the first course_enrollment_settings so that there's no case_value, causing MySQL to know that you intend to use the second variant of CASE:

CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
END CASE

Now you can provide your full conditionals as search_condition.

Also, please read the documentation for features that you use.


SELECT
   CASE 
    WHEN course_enrollment_settings.base_price = 0      THEN 1
    WHEN course_enrollment_settings.base_price>0 AND  
         course_enrollment_settings.base_price<=100     THEN 2
    WHEN course_enrollment_settings.base_price>100 AND   
         course_enrollment_settings.base_price<201      THEN 3
        ELSE 6
   END AS 'calc_base_price',
   course_enrollment_settings.base_price
FROM
    course_enrollment_settings
WHERE course_enrollment_settings.base_price = 0

CASE case_value
    WHEN when_value THEN statements
    [WHEN when_value THEN statements]
    ELSE statements
END 

Or:

CASE
WHEN <search_condition> THEN statements
[WHEN <search_condition> THEN statements] 
ELSE statements
END 

here CASE is an expression in 2nd scenario search_condition will evaluate and if no search_condition is equal then execute else

SELECT
   CASE course_enrollment_settings.base_price
    WHEN course_enrollment_settings.base_price = 0      THEN 1

should be

SELECT
   CASE 
    WHEN course_enrollment_settings.base_price = 0      THEN 1

CASE course_enrollment_settings.base_price is wrong here, it should be just CASE

SELECT 
CASE 
WHEN course_enrollment_settings.base_price = 0      THEN 1 
WHEN course_enrollment_settings.base_price<101      THEN 2 
WHEN course_enrollment_settings.base_price>100 AND    
                  course_enrollment_settings.base_price<201 THEN 3 
    ELSE 6 
END AS 'calc_base_price', 
course_enrollment_settings.base_price 
FROM 
  course_enrollment_settings 
WHERE course_enrollment_settings.base_price = 0 

Some explanations. Your original query will be executed as :

SELECT 
CASE 0
WHEN 0=0 THEN 1 -- condition evaluates to 1, then 0 (from CASE 0)compares to 1 - false
WHEN 0<1 THEN 2 -- condition evaluates to 1,then 0 (from CASE 0)compares to 1 - false
WHEN 0>100 and 0<201 THEN 3 -- evaluates to 0 ,then 0 (from CASE 0)compares to 0 - true
ELSE 6, ...

it's why you always get 3


Examples related to mysql

Implement specialization in ER diagram How to post query parameters with Axios? PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver' phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' is not supported How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Connection Java-MySql : Public Key Retrieval is not allowed How to grant all privileges to root user in MySQL 8.0 MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

Examples related to sql

Passing multiple values for same variable in stored procedure SQL permissions for roles Generic XSLT Search and Replace template Access And/Or exclusions Pyspark: Filter dataframe based on multiple conditions Subtracting 1 day from a timestamp date PYODBC--Data source name not found and no default driver specified select rows in sql with latest date for each ID repeated multiple times ALTER TABLE DROP COLUMN failed because one or more objects access this column Create Local SQL Server database

Examples related to conditional

Pandas/Python: Set value of one column based on value in another column Run an Ansible task only when the variable contains a specific string (Excel) Conditional Formatting based on Adjacent Cell Value Laravel Checking If a Record Exists Multiple conditions in if statement shell script The condition has length > 1 and only the first element will be used Creating a new column based on if-elif-else condition How to conditional format based on multiple specific text in Excel Using SUMIFS with multiple AND OR conditions Replacing Numpy elements if condition is met

Examples related to switch-statement

Switch in Laravel 5 - Blade Switch case: can I use a range instead of a one number SQL use CASE statement in WHERE IN clause SSRS Conditional Formatting Switch or IIF Switch statement equivalent in Windows batch file OR operator in switch-case? Regarding Java switch statements - using return and omitting breaks in each case Using two values for one switch case statement C# how to use enum with switch Switch statement multiple cases in JavaScript

Examples related to case

PostgreSQL CASE ... END with multiple conditions SQL Server: use CASE with LIKE SQL Server IIF vs CASE SELECT using 'CASE' in SQL SELECT query with CASE condition and SUM() GROUP BY + CASE statement SQL use CASE statement in WHERE IN clause SQL Server - Case Statement where to place CASE WHEN column IS NULL in this query Regarding Java switch statements - using return and omitting breaks in each case