2017-02-09 122 views
-1
RefNo Title 
----- ----- 
12  Check 
12  With Sample 
13  Cash 
13  With Sample 
14  Cash 
14  Check 
15  Deposit 
15  Check 

我有這張表,我想要下面的輸出。如果有「隨着樣本」,然後「隨着樣品」如何在SQL Server中有多個條件CASE WHEN?

否則,如果有「現金」和

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 

基本上具有相同引用號行的說明會有這個優先「隨着樣品」然後「你好」

ELSE如果有「現金」然後「現金」

ELSE如果有「檢查」,那麼「檢查」

該描述適用於所有具有相同RefNo的行。謝謝。

+0

每個參考將只有2個標題? –

+0

根據你想要的結果,'Hello'條件應該先去,否則你會在這些情況下'With Sample'。 – Andrew

回答

2

你需要對每個組的RefNo行申請窗總結:

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 
+0

您需要將'Hello'條件移至第一個位置,否則將顯示'With Sample'。 – Andrew

+0

@Andrew:是的,我剛剛翻譯了原來的邏輯,顯然是錯的:-)修正了這個問題,謝謝 – dnoeth

-1

下面的查詢會給你想要的結果

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 
+0

我沒有失望,但儘管現在有效,但很難維護。如果你需要考慮第三種狀態呢?您需要添加另一個自加入... – Andrew

+0

如果每個RefNo有超過2行,會發生什麼情況?順便說一句,實際上它是一個基於非等式而不是「交叉連接」的「內部連接」。 – dnoeth

0

也許還有另一種方法,但我的是如下: -

  1. 使用XML PATH連接基於I D.
  2. 使用Case在您的條件之間切換。

演示: -

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 

結果: -

enter image description here

+0

相當矯枉過正,容易出錯。例如,如果您將「Cash」添加到RefNo 12,您將獲得「Cash」而不是「Hello」。您正在依靠名稱來排序標題,這正在呼喚未來的麻煩(除了已有的麻煩外)。 – Andrew

0

dnoeth的回答可能是最好的一個(只需要在它的狀態以便固定,正如我評論的那樣),但是我想到了其他人可能會喜歡的方法:

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 

正如您所看到的,我爲每個標題分配了2個值的冪,然後使用按位運算符來標識每個個案。

+0

希望每個標題不會超過一行:-) – dnoeth

+0

我明白你的意思了。例如,在這種情況下,您需要在CTE中使用'FROM(SELECT DISTINCT RefNo,Title FROM YourTable)YT'。 – Andrew