简体   繁体   中英

How can I use CASE expression in my query?

When I want to execute my case statement it shows some error.

I have created a Demographics query. So, I need to include the case statement.

SELECT DISTINCT
    'Age' DemographicGroup,
    CASE
        WHEN DATEDIFF(YY, DOB, @ReportDate) 25 THEN '=25' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 25 AND 35 THEN '26-35' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 36 AND 45 THEN '36-45' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) 45 THEN '46+'
    END Label, 

    CASE
        WHEN DATEDIFF(YY, DOB, @ReportDate) 25 THEN 1 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 25 AND 35 THEN 2 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 36 AND 45 THEN 3 
        WHEN DATEDIFF(YY, DOB, @ReportDate) 45 THEN 4
    END GroupOrder
INTO
    #Demo2
FROM
    [dbo].[Dim_Borrower]

Msg 102, Level 15, State 1, Line 4
Incorrect syntax near '25'

Msg 102, Level 15, State 1, Line 7
Incorrect syntax near 'Label'

Msg 102, Level 15, State 1, Line 11
Incorrect syntax near 'GroupOrder'

You need to use comparison operators inside your WHEN expressions. Like = , < , > , <> , etc.

You should also add an explicit ELSE case to avoid unintentional NULL output:

SELECT DISTINCT
    'Age' DemographicGroup,
    CASE
        WHEN DATEDIFF(YY, DOB, @ReportDate) = 25              THEN '=25' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 25 AND 35 THEN '26-35' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 36 AND 45 THEN '36-45' 
        WHEN DATEDIFF(YY, DOB, @ReportDate) > 45              THEN '46+'
        ELSE 'Unknown'
    END AS [Label], 

    CASE
        WHEN DATEDIFF(YY, DOB, @ReportDate) = 25              THEN 1 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 25 AND 35 THEN 2 
        WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 36 AND 45 THEN 3 
        WHEN DATEDIFF(YY, DOB, @ReportDate) > 45              THEN 4
        ELSE 5
    END AS [GroupOrder]
INTO
    #Demo2
FROM
    [dbo].[Dim_Borrower]

You can simplify this to reduce repetitive code by using an inner-query and using the simpler CASE xpr WHEN val instead of the longer-form CASE WHEN expr .

SELECT DISTINCT
    'Age' AS DemographicGroup,
    CASE q0.AgeGroup
        WHEN 1 THEN '=25' 
        WHEN 2 THEN '26-35' 
        WHEN 3 THEN '36-45' 
        WHEN 4 THEN '46+'
        ELSE 'Unknown'
    END AS [Label], 
    q0.AgeGroup AS [GroupOrder]
INTO
    #Demo2
FROM
    (
        SELECT
            'Age' AS DemographicGroup,
            CASE
                WHEN DATEDIFF(YY, DOB, @ReportDate) = 25              THEN 1 
                WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 25 AND 35 THEN 2 
                WHEN DATEDIFF(YY, DOB, @ReportDate) BETWEEN 36 AND 45 THEN 3 
                WHEN DATEDIFF(YY, DOB, @ReportDate) > 45              THEN 4
                ELSE 5
            END AS AgeGroup
        FROM
            [dbo].[Dim_Borrower]
    ) AS q0


A case for APPLY. Also you needn't BETWEEN because CASE Evaluates, in the order specified, Boolean_expression for each WHEN clause

SELECT DISTINCT
    'Age' DemographicGroup,
    CASE g.[GroupOrder]
        WHEN 1 THEN '=25' 
        WHEN 2 THEN '26-35' 
        WHEN 3 THEN '36-45' 
        WHEN 4 THEN '46+'
        ELSE 'Unknown'
    END AS [Label], 
    g.[GroupOrder]
INTO
    #Demo2
FROM
    [dbo].[Dim_Borrower]
CROSS APPLY (
   SELECT CASE
        WHEN DATEDIFF(YY, DOB, @ReportDate) = 25  THEN 1 
        WHEN DATEDIFF(YY, DOB, @ReportDate) <= 35 THEN 2 
        WHEN DATEDIFF(YY, DOB, @ReportDate) <= 45 THEN 3 
        WHEN DATEDIFF(YY, DOB, @ReportDate) > 45  THEN 4
        ELSE 5
    END AS [GroupOrder]
) g

I am confused why you are referring to any table at all. Why not just use a derived table with the values you want?

select 'Age' as DemographicGroup,
into #Demo2
from (values (1, '=25'),
             (2, '26-35'),
             (3, '36-45'),
             (4, '46+')
     ) v(Label, GroupOrder);

This ensures that all values get into the table, regardless of whether Dim_Borrower has them.

I would also include the lower and upper bounds of the age range so I can join this to other data:

select 'Age' as DemographicGroup,
into #Demo2
from (values (1, '=25', 25, 25),
             (2, '26-35', 26, 35),
             (3, '36-45', 36, 45),
             (4, '46+', 46, NULL)
     ) v(Label, GroupOrder, LowerAge, UpperAge);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM