2016-07-20 287 views
1

我有一個表,如下所示:TSQL Case語句

enter image description here

我怎樣寫一個case語句拉出只有最新的利率,在這種情況下會Rate14?任何時候,費率爲0.0000,那麼我需要回到先前的費率。

任何幫助,將不勝感激。

+3

正常化數據庫模式將是理想的。 – HardCode

+0

對。我是SSRS報告撰稿人,只能使用提供的內容。試圖讓它工作。 SQL開發人員無法規範化數據。 -sigh- – BIReportGuy

+1

你能解釋一下如何工作嗎?定義'最新'....最新的每個comlumn是0?在這種情況下,'Rate14'將會是0嗎? –

回答

7
Select 
    Case When Rate15 > 0 Then Rate15 
     When Rate14 > 0 Then Rate14 
     ... 
     When Rate2 > 0 Then Rate2 
     Else Rate1 
    End Rate 
From Table 
+0

通過蠻力簡化。有時候這是最好的答案。 –

+0

我是否總是需要從最後一個費率字段(費率15)到最早的費率(費率1)才能正常工作?它看起來很... – BIReportGuy

+1

@BIGuy當然,因爲'CASE'表達式在第一個命中後會退出。 –

3

完全同意@Joe C(+1),「蠻力」是最簡單的方法。正因爲如此,我沒有其他理由而僅僅爲了證明大案例的簡單性而證明這一點。 (另外,這是很容易對付的大case語句中的「無數據」的情況。)

首先,設置了一些樣本數據:

--DROP TABLE MyTable 
GO 

CREATE TABLE MyTable 
(
    CUSIPNumber varchar(20) not null 
    ,Year   smallint  not null 
    ,Rate1  float  not null 
    ,Rate2  float  not null 
    ,Rate3  float  not null 
    ,Rate4  float  not null 
    ,Rate5  float  not null 
    ,Rate6  float  not null 
    ,Rate7  float  not null 
    ,Rate8  float  not null 
    ,Rate9  float  not null 
    ,Rate10  float  not null 
    ,Rate11  float  not null 
    ,Rate12  float  not null 
    ,Rate13  float  not null 
    ,Rate14  float  not null 
    ,Rate15  float  not null 
) 

INSERT MyTable values 
    ('001383EA2', 16, 4.0505, 4.0510, 4.0515, 4.0520, 4.0525, 4.0530, 4.0535, 4.0550, 4.0545, 4.0550, 4.0560, 4.0570, 4.0575, 4.0585, 0) 
,('001383EA2', 15, 3.0505, 3.0510, 3.0515, 3.0520, 3.0525, 3.0530, 3.0535, 3.0550, 3.0545, 3.0550, 3.0560, 3.0570, 3.0575, 3.0585, 3.0599) 
,('001383__1', 01, 1.1, 2.2, 3.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
,('001383_NoData', 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 

-- What we have 
SELECT * 
from MyTable 

這裏是基本的逆轉置聲明。列是別名/重命名,允許最大值()來識別最新的項目(率2爲> Rate11 ...)

-- Build the unpivot statement 
SELECT * 
from (select CUSIPNumber, Year, Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15 
     from MyTable) src 
unpivot (RateValue 
      for RateNumber in (Rate1, Rate3, Rate4, Rate5, Rate6, Rate7, Rate8, Rate9, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
     ) unpvt 

-- Whoops! Alias the "Rate" columns, so that they can be sorted 
SELECT * 
from (select 
      CUSIPNumber 
     ,Year 
     ,Rate1 Rate01 
     ,Rate2 Rate02 
     ,Rate3 Rate03 
     ,Rate4 Rate04 
     ,Rate5 Rate05 
     ,Rate6 Rate06 
     ,Rate7 Rate07 
     ,Rate8 Rate08 
     ,Rate9 Rate09 
     ,Rate10 
     ,Rate11 
     ,Rate12 
     ,Rate13 
     ,Rate14 
     ,Rate15 
     from MyTable) src 
unpivot (RateValue 
      for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
     ) unpvt 

這個數據需要被多次引用。要做到這一點最簡單的方法是讓一個CTE:

-- Make it a Common Table Expression 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select * 
from ctePvt 

有了這個,我們可以判斷最近利率

-- This determines the most recent rate 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select 
    CUSIPNumber 
    ,Year 
    ,max(RateNumber) CurrentRate 
    from ctePvt 
    where RateValue <> 0 
group by 
    CUSIPNumber 
    ,Year 

有了這樣的,我們終於可以得到價值爲最近率

-- This gest the values for the most recent rate 
WITH ctePvt 
as (select CUSIPNumber, Year, RateNumber, RateValue 
     from (select 
       CUSIPNumber 
       ,Year 
       ,Rate1 Rate01 
       ,Rate2 Rate02 
       ,Rate3 Rate03 
       ,Rate4 Rate04 
       ,Rate5 Rate05 
       ,Rate6 Rate06 
       ,Rate7 Rate07 
       ,Rate8 Rate08 
       ,Rate9 Rate09 
       ,Rate10 
       ,Rate11 
       ,Rate12 
       ,Rate13 
       ,Rate14 
       ,Rate15 
      from MyTable) src 
     unpivot (RateValue 
       for RateNumber in (Rate01, Rate02, Rate03, Rate04, Rate05, Rate06, Rate07, Rate08, Rate09, Rate10, Rate11, Rate12, Rate13, Rate14, Rate15) 
      ) unpvt) 
select 
    cteBase.CUSIPNumber 
    ,cteBase.Year 
    ,cteBase.RateValue 
    from ctePvt cteBase 
    inner join (-- Most recent rate per item 
       select 
        CUSIPNumber 
       ,Year 
       ,max(RateNumber) CurrentRate 
       from ctePvt 
       where RateValue <> 0 
       group by 
        CUSIPNumber 
       ,Year) cteRecent 
    on cteRecent.CUSIPNumber = cteBase.CUSIPNumber 
    and cteRecent.Year = cteBase.Year 
    and cteRecent.CurrentRate = cteBase.RateNumber 

請注意,這不會返回沒有價格值的項目的行。有很多方法可以解決,但足夠。

難道你很高興你與大案的陳述?

3

稍微簡潔的方法如下,但完全展開的CASE版本可能更清晰且更高效。

Select COALESCE(NULLIF(Rate15,0), 
       NULLIF(Rate14,0), 
       NULLIF(Rate13,0), 
       ... 
       NULLIF(Rate3,0), 
       NULLIF(Rate2,0), 
          Rate1 
       ) AS Rate 
From Table 
+0

我也在想這個,如果基礎數據有null而不是0 –