2016-07-20 212 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 –