Create a calculated column in SQL using CASE WHEN and IN

780 views Asked by At

How can I create a new set of columns that searches a row for specific codes and flags a Yes or No based on the search criteria in Oracle SQL and MySQL?

Background:

I have a Customer code table that contains ~20+ columns with codes associated with the CustomerID record. Unfortunately, the columns are not tied to a specific code, as a result, each column can contain any code.

Customer Code 

CustomerID |col1|col2|col3|col4|col5|...|col20|
-----------------------------------------------
A          | 0   |  0 |  10| 19 | 200|...| 50 |
B          | 1   | 5  | 19 | 0  | 50 |...| 8  |
...   

The goal is to create a subquery that contains several columns with the Customer ID that will indicate if the Customer has a specific code associated with them. For example, create a Code 10, Code 19, and Code 5 column and flag is as "Y" for each CustomerID if they have a code 10, 19, or 5 in any of the 20 columns in the table,

The result would look something like this.. (new columns in bold)

CustomerID |col1|col2|col3|col4|col5|...|col20| **Code 10**| **Code 19** | **Code 5**
------------------------------------------------------------------------------------
A          | 0   |  0 |  10| 19 | 200|...| 50 |  **Y**     |    **Y**    | **N**
B          | 1   | 5  | 19 | 0  | 50 |...| 8  |  **N**     |    **Y**    | **Y**
...

Current Process that works in Excel: In Excel, I would create a new column called "All Codes" and concatenate all the columns containing codes.

The new column would look like this:

|      All Codes      |
----------------------
|0 0 10 19 200 ... 50 | 
|1 5 19 0  50   ... 8 |

After creating a concatenate helper column, I then create a new column for each code I need using an if and contain text function. Results would look like below:

|    All Codes        | Code 10 | Code 19 | Code 5 
-------------------------------------------------------
|0 0 10 19 200 ... 50 |  Y      |  Y      | N
|1 5 19 0  50   ... 8 |  N      |  Y      | Y

Then I would remove the All Codes and join the new table with the CustomerID table.

Thank you for your time!

2

There are 2 answers

0
Gordon Linoff On BEST ANSWER

Use case and in:

select t.*,
       (case when 10 in (col1, col2, . . .)
             then 'Y' else 'N'
        end) as cod_10,
       (case when 19 in (col1, col2, . . .)
             then 'Y' else 'N'
        end) as cod_19,
       (case when 5 in (col1, col2, . . .)
             then 'Y' else 'N'
        end) as cod_5
from t;

The . . . is for the rest of the code columns.

This is standard SQL and should work in any database.

I would recommend that you change the data structure. You should have a table with one row per customerId and code, a customerCodes table.

5
Akina On

On your denormalized structure you may use something like

WITH cte AS ( SELECT *, CONCAT_WS(',', col1, col2, ... , col20) total
              FROM source_table )
SELECT *, CASE WHEN FIND_IN_SET(10, total) THEN 'Y' ELSE 'N' END AS Code10
FROM cte