简体   繁体   中英

How to have multiple conditions in SQL Server CASE WHEN?

RefNo   Title
-----   -----
12      Check
12      With Sample
13      Cash
13      With Sample
14      Cash
14      Check
15      Deposit
15      Check

I have this table that I want to have the output below.

RefNo   Title        Desc
-----   -----        -----
12      Check        With Sample
12      With Sample  With Sample
13      Cash         Hello
13      With Sample  Hello
14      Cash         Cash
14      Check        Cash
15      Deposit      Check
15      Check        Check

Basically in the rows with the same RefNo the Description would have this priority:

If there is 'With Sample' THEN 'With Sample'

ELSE IF there is 'Cash' AND 'With Sample' THEN 'Hello'

ELSE IF there is 'Cash' THEN 'Cash'

ELSE IF there is 'Check' THEN 'Check'

The description applies to all the rows with the same RefNo. Thank you.

You need to apply Windowed Aggregate on each group of RefNo rows:

WITH cte AS 
 (
   SELECT
       Max(CASE WHEN Title = 'With Sample' THEN 1 ELSE 0 end) Over (PARTITION BY RefNo) AS SampleFlag
      ,Max(CASE WHEN Title = 'Cash'        THEN 1 ELSE 0 end) Over (PARTITION BY RefNo) AS CashFlag
      ,Max(CASE WHEN Title = 'Check'       THEN 1 ELSE 0 end) Over (PARTITION BY RefNo) AS CheckFlag
      ...
   FROM tab
 ) 
SELECT
   CASE
      WHEN SampleFlag + CashFlag = 2 THEN 'Hello'
      WHEN SampleFlag = 1            THEN 'With Sample'
      WHEN CashFlag = 1              THEN 'Cash'
      WHEN CheckFlag = 1             THEN 'Check'
   END
   ...
FROM cte

Maybe there are another approaches, but mine is as following:-

  1. Use XML PATH for concatenating the values based on ID.
  2. Use Case for switching between your conditions.

Demo:-

declare @MyTable table (RefNo int ,Title varchar(20) )
insert into @MyTable values (12 , 'Check')
insert into @MyTable values (12 , 'With Sample')
insert into @MyTable values (13 , 'Cash')
insert into @MyTable values (13 , 'With Sample')
insert into @MyTable values (14 , 'Cash')
insert into @MyTable values (14 , 'Check')
insert into @MyTable values (15 , 'Deposit')
insert into @MyTable values (15 , 'Check')

select RefNo , Title ,  case  
                            when ( SELECT Title + ',' 
                                    FROM @MyTable p2
                                    WHERE p1.RefNo = p2.RefNo
                                    ORDER BY Title
                                    FOR XML PATH('') ) like '%With Sample%' 
                                    AND
                                    ( SELECT Title + ',' 
                                    FROM @MyTable p2
                                    WHERE p1.RefNo = p2.RefNo
                                    ORDER BY Title
                                    FOR XML PATH('') ) not like '%Cash%' 
                            then 'With Sample'
                            when ( SELECT Title + ',' 
                                    FROM @MyTable p2
                                    WHERE p1.RefNo = p2.RefNo
                                    ORDER BY Title
                                    FOR XML PATH('') ) like  '%Cash,With Sample,%' 
                            then 'Hello'

                            when ( SELECT Title + ',' 
                                    FROM @MyTable p2
                                    WHERE p1.RefNo = p2.RefNo
                                    ORDER BY Title
                                    FOR XML PATH('') ) like '%Cash%' 
                            then 'Cash'
                            when ( SELECT Title + ',' 
                                    FROM @MyTable p2
                                    WHERE p1.RefNo = p2.RefNo
                                    ORDER BY Title
                                    FOR XML PATH('') ) like '%Check%' 
                            then 'Check'
                            end [Desc]

from @MyTable  p1

Result:-

在此处输入图片说明

dnoeth's answer is probably the best one (it only needs to have its condition order fixed, as I commented), but I thought of this other approach which someone may like:

WITH cte AS
(
    SELECT RefNo, SUM(CASE Title WHEN 'With Sample' THEN 4 WHEN 'Cash' THEN 2 WHEN 'Check' THEN 1 END) Total
    FROM YourTable
    GROUP BY RefNo
)
SELECT YT.RefNo, Title, CASE
    WHEN Total & 6 = 6 THEN 'Hello'
    WHEN Total & 4 = 4 THEN 'With Sample'
    WHEN Total & 2 = 2 THEN 'Cash'
    WHEN Total & 1 = 1 THEN 'Check' END AS "Desc"
FROM YourTable YT
INNER JOIN cte ON YT.RefNo = cte.RefNo

As you can see, I'm assigning power of 2 values to each title and then use bitwise operators to identify each case.

Below Query Will give you the desired result

select t1.RefNo, t1.Title, case
WHEN (t1.Title = 'Check' AND t2.Title = 'With Sample') OR (t2.Title = 'Check' AND t1.Title = 'With Sample') Then 'With Sample'
WHEN (t1.Title = 'Cash' AND t2.Title = 'With Sample') OR (t2.Title = 'Cash' AND t1.Title = 'With Sample') Then 'Hello'
WHEN (t1.Title = 'Cash' AND t2.Title = 'Check') OR (t2.Title = 'Cash' AND t1.Title = 'Check') Then 'Cash'
WHEN (t1.Title = 'Check' AND t2.Title = 'Deposit') OR (t2.Title = 'Check' AND t1.Title = 'Deposit') Then 'Check'
END
 from TestCase t1 cross join TestCase t2 where t1.Title != t2.Title and t1.RefNo = t2.RefNo

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