A SQL CASE statement evaluates and returns results based on particular values, predicates and conditions as per defined logic. For example, suppose you have a voters table with the following details:

  • Voter ID
  • Name
  • DOB

If you were looking for logic about voting eligibility, this would be dependent upon the values in the DOB column.

If a voter’s age is greater than 18, they are eligible to vote.

SQL Case statement example of voter’s age.

Let's look at another example. Many times, we store the column values in bits 1 or 0. Let's say you store the values for a product’s availability as 1 or 0. For example:

  • 1 = Product is available
  • 0 = Product is out of stock

If we look at the database perspective, it is a good practice to use the abbreviations or bits wherever possible. It is beneficial for the SQL Server query optimizer in preparing the optimized execution plan. But, from the application perspective, the end-user does not require these values. Customers just need to view whether the product is available or not.

In the below image, we see both the database and application perspective.

What does the SQL CASE statement do?

 A CASE statement in SQL Server evaluates an expression and returns a value based on the defined conditions. Therefore, in the earlier example, the CASE statements work as shown below.

At a high-level, the syntax for a SQL CASE statement is shown below. Here, we specified multiple conditions. SQL Server evaluates the conditions sequentially. Once a condition evaluates successfully, it stops the evaluation of remaining conditions. If none of the conditions are satisfied, we can use an optional ELSE statement to return the default value. For example, if we have a value different then 0 and 1 in the availability column, you get the output from the ELSE code block. It requires at least one set of the WHEN and THEN blocks. The CASE statement must end with the END block.

The syntax for a SQL CASE statement

Let's explore the SQL CASE statement using various examples.

Note: In this article, we use the Microsoft sample database, AdventureWorks. You can download its backup from the Microsoft Docs.

The SELECT statement with a simple CASE expression


In this type of CASE statement, we use equality check expressions. The following query implements a simple CASE expression.

  • If the value in the [SalariedFlag] is 1, then it shows the Active Employee
  • For all other values, it displays the output as Inactive Employee

SELECT TOP 5 Nationalidnumber ,
             CASE salariedflag
               WHEN 1 THEN 'Active Employee'
               ELSE 'Inactive Employee'
             END AS [Salaried Flag]
FROM   [AdventureWorks2019].[HumanResources].[employee]  

  

We can specify multiple conditions for the CASE statement.

SELECT TOP 5 Nationalidnumber ,
             CASE salariedflag
               WHEN 1 THEN 'Active Employee'
               WHEN 0 THEN 'Inactive Employee'
               ELSE 'Invalid Value'
             END AS [Salaried Flag]
FROM   [AdventureWorks2019].[HumanResources].[employee]  

Data standardization using SQL CASE statements

Usually, we use abbreviations to store values in SQL tables. The standard abbreviations are gender, country codes, marriage status, popular product names, etc.

Suppose we specify the abbreviations for storing employee genders. Now, our application should display the results without any abbreviations.

SQL CASE statements help to standardize the output for defined criteria. In the below query, we use the following conditions:

  • If the gender value is M, display it as Male
  • If the gender value is F, display it as Female
  • For any other values, display Invalid Value

SELECT DISTINCT CASE gender
                  WHEN 'M' THEN 'Male'
                  WHEN 'F' THEN 'Female'
                  ELSE 'Invalid Value'
                END AS Gender
                FROM   AdventureWorks2019.HumanResources.Employee  

 

    

Searched CASE statements

In the searched CASE statement, we specify a CASE expression instead of the direct values. Once the expression value evaluates and satisfies a condition in the WHEN clause, its corresponding value is returned.

Look at the below SQL query. Here, we defined expressions in the WHEN clause for the [ListPrice]. It identifies that the product cost is $250 and is marked as an Electronics item.

SELECT  ProductNumber, Name, [Product category] =   
      CASE   
         WHEN ListPrice =  0 THEN 'Out of Stock items'  
         WHEN ListPrice > 0 and  ListPrice<=100 THEN 'Consumer goods'  
         WHEN ListPrice >100 and ListPrice <= 500 THEN 'Electronics items'  
         WHEN ListPrice >500 and ListPrice < 1500 THEN 'Luxury items'  
         ELSE 'Extra items'  
      END  
FROM Production.Product  order by ListPrice desc

For the gender example referred to earlier, we can rewrite the SQL CASE statement for the gender abbreviations using the searched case statements.

SELECT DISTINCT CASE 
                  WHEN Gender='M' THEN 'Male'
                  WHEN Gender='F' THEN 'Female'
                  ELSE 'Invalid Value'
                END AS Gender
                FROM   AdventureWorks2019.HumanResources.Employee  

  

Using CASE statements with the ORDER BY clause

SQL queries use the ORDER BY clause for data sorting in either ascending or descending order. You can use the CASE statements in conjunction with the ORDER BY clause. Suppose from the products table, we retrieve the [ProductName] and [ListPrice]. We want to sort the results in the following ways:

  • If the product list price is less than 2,000, you want the result in the default sort order, i.e., ascending
  • If the product list price is greater than 2,000, the ORDER BY clause sort results in descending order

In this query, we use two SQL CASE statements to implement the logic.

SELECT   Name,
         ListPrice
FROM     Production.Product
ORDER BY CASE
            WHEN  ListPrice<=2000 THEN ListPrice END 
            ,CASE WHEN ListPrice >2000  THEN ListPrice END DESC 

  

In the below query output, you can verify the data sorts appearing in both descending and ascending order.

In another example, suppose we want to sort data in the employee table based on the following condition:

  • For active employees (Current flag =1), data should sort the hire date column
  • For inactive employees, it should sort data as per the values in the birthdate column

SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflag
                FROM   AdventureWorks2019.HumanResources.Employee  
                ORDER BY 
                CASE CURRENTFLAG WHEN 1 THEN HireDate 
                                else Birthdate 
                                end 

 In the query output, we can verify the data sort order defined by the ORDER BY clause and CASE statements.

CASE statement in SQL and aggregate functions

Aggregate functions in SQL Server perform calculations and return a single value. Examples of aggregate functions are MIN, MAX, COUNT, ABG and CHECKSUM.

Suppose we want to retrieve the employee hire count for each year from 2007-2010. It should display results in the following format:

For this purpose, we use the COUNT aggregate function in SQL Server.

  • First, the SQL DATEPART function filters data according to the year. For example, the DATEPART(YY, Hiredate)=2007, filters data for the year 2007.
  • We then use the CASE statement to return 1 if the year is 2007.
  • The count aggregate function counts the records and displays the results.
  • Similarly, the query works for the remaining years.

SELECT Count(CASE
               WHEN Datepart(yy, hiredate) = 2007 THEN 1
               ELSE NULL
             END) AS [2007Hires],
       Count(CASE
               WHEN Datepart(yy, hiredate) = 2008 THEN 1
               ELSE NULL
             END) AS [2008Hires],
       Count(CASE
               WHEN Datepart(yy, hiredate) = 2009 THEN 1
               ELSE NULL
             END) AS [2009Hires],
       Count(CASE
               WHEN Datepart(yy, hiredate) = 2009 THEN 1
               ELSE NULL
             END) AS [2010Hires]
FROM   AdventureWorks2019.HumanResources.Employee 

Similarly, let's say we want to use the aggregate function GROUP BY to group rows having the same product category. We can specify the CASE statement in SQL to sort data from the grouped result set.

SELECT [Product category] = CASE
                              WHEN listprice = 0 THEN 'Out of Stock items'
                              WHEN listprice > 0
                                   AND listprice <= 100 THEN 'Consumer goods'
                              WHEN listprice > 100
                                   AND listprice <= 500 THEN 'Electronics items'
                              WHEN listprice > 500
                                   AND listprice < 1500 THEN 'Luxury items'
                              ELSE 'Extra items'
                            END,
       Min(listprice)   AS MinPrice,
       Max(listprice)   AS MaxPrice,
       Count(listprice) AS Numberofproducts
FROM   production.product
GROUP  BY CASE
            WHEN listprice = 0 THEN 'Out of Stock items'
            WHEN listprice > 0
                 AND listprice <= 100 THEN 'Consumer goods'
            WHEN listprice > 100
                 AND listprice <= 500 THEN 'Electronics items'
            WHEN listprice > 500
                 AND listprice < 1500 THEN 'Luxury items'
            ELSE 'Extra items'
          END
ORDER  BY numberofproducts DESC  


In the above query, we use two SQL CASE statements.

  • The first CASE statement categorizes the data based on the expression defined in the list price. Using this CASE statement, we divide the products into the following categories:
    • Out of Stock items
    • Consumer goods
    • Electronic items
    • Luxury items
  • In the second case statement, we use the GROUP BY aggregate function to group the result by the category
  • Further, we sort the results as per the NumberOfProducts in the descending order

 

Prevent divide by zero error using SQL CASE statements

A divide by zero error occurs if the denominator value is zero. If you do these fractions in SQL Server, it will give you the divide by zero error as shown below.

It is an excellent practice to write your queries in a way to avoid these common mistakes. To avoid this, we use the fraction logic inside a CASE statement.

DECLARE @Student1 INT
DECLARE @Student2 INT

SET @Student1=100
SET @Student2=0

select
CASE WHEN @Student2=0
THEN NULL
ELSE @Student1/@Student2 end as StudentMarksRatio

We have safeguarded our query from the divide by zero error. Now, with the modified logic, if we get a zero in the denominator, you get NULL in the output as shown below.

Helpful reminders about the SQL CASE statement

  • SQL CASE statements support up to 10 levels of nesting
  • You cannot control the flow of executions of the statements, functions or procedures using CASE expressions
  • You should always use an ELSE block so that if any conditions are not satisfied, you get a default value
  • You should avoid using conflicting conditions in the SQL CASE statement. The CASE statement works sequentially and stops evaluating with the first successful condition
Anonymous
Related Content