TSQL案例语句

TSQL案例语句,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一张这样的桌子: 我如何编写一份案例陈述,以仅提取最新的费率,在本例中为费率14?任何时候利率是0.0000,那么我就需要回到以前的利率 任何帮助都将不胜感激。完全同意@Joe C+1,暴力是最简单的方法。正因为如此,我进行了构建unpivot的练习,如果没有其他原因的话,就是为了证明big case语句的简单性。此外,使用big case语句处理无数据情况要容易得多 Select Case When Rate15 > 0 Then Rate15 When R

我有一张这样的桌子:

我如何编写一份案例陈述,以仅提取最新的费率,在本例中为费率14?任何时候利率是0.0000,那么我就需要回到以前的利率


任何帮助都将不胜感激。

完全同意@Joe C+1,暴力是最简单的方法。正因为如此,我进行了构建unpivot的练习,如果没有其他原因的话,就是为了证明big case语句的简单性。此外,使用big case语句处理无数据情况要容易得多

Select
    Case When Rate15 > 0 Then Rate15
         When Rate14 > 0 Then Rate14
         ...
         When Rate2 > 0 Then Rate2
         Else Rate1
    End Rate
From Table
首先,设置一些示例数据:

--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
这是基本的unpivot语句。列具有别名/重命名,以允许max识别最新的项Rate2 is>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
请注意,对于没有速率值的项目,这不会返回任何行。有几个方法可以解决,但已经足够了


你不高兴你接受了重大案件的陈述吗

完全同意@Joe C+1,暴力是最简单的方法。正因为如此,我进行了构建unpivot的练习,如果没有其他原因的话,就是为了证明big case语句的简单性。此外,使用big 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
这是基本的unpivot语句。列具有别名/重命名,以允许max识别最新的项Rate2 is>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
请注意,对于没有速率值的项目,这不会返回任何行。有几个方法可以解决,但已经足够了


你不高兴你接受了重大案件的陈述吗

下面是一种略为简洁的方法,但完全扩展的案例版本可能更清晰、更有效

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

下面是一种略为简洁的方法,但完全扩展的案例版本可能更清晰、更有效

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

规范化数据库模式将是理想的选择。我是SSRS报告作者,只能使用提供的内容。努力让它工作。SQL开发人员无法规范化数据-你能解释一下它是怎么工作的吗?定义最新的。。。。最近一次之后的每个ComColumn都是0?在这种情况下,after Rate 14将为0?您可以使用将列更改为行。这样处理数据就容易多了。规范化数据库模式将是理想的选择。对。我是SSRS报告作者,只能使用提供的内容。努力让它工作。SQL开发人员无法规范化数据-你能解释一下它是怎么工作的吗?定义最新的。。。。最近一次之后的每个ComColumn都是0?在这种情况下,after Rate 14将为0?您可以使用将列更改为行。这样处理数据就容易多了。通过蛮力简化。有时这是最好的答案。我是否总是需要从最后一个rate字段rate15到最早的rate1,才能使本案例陈述生效?看起来是这样的…@BIGuy肯定是这样的,因为在第一个临界点出现之后会出现一个CASE表达式。是的,我只是想直接回答,因为我看到很多在这里提问的人没有能力改变设计,至少在他们必须解决当前的解决方案之前是这样。我确实同意其他人的看法,即最好的方案是有更好的设计,但我没有重申其他人已经发表的意见。@BIGuy案例陈述应按优先级排序,因为Hart共同评论案例陈述在第一个满足条件时退出。通过暴力简化。有时这是最好的答案。我是否总是需要从最后一个rate字段rate15到最早的rate1,才能使本案例陈述生效?看起来是这样的…@BIGuy肯定是这样的,因为在第一个临界点出现之后会出现一个CASE表达式。是的,我只是想直接回答,因为我看到很多在这里提问的人没有能力改变设计,至少在他们必须解决当前的解决方案之前是这样。我确实同意其他人的看法,即最好的方案是有更好的设计,但我没有重申其他人已经发表的意见。@BIGuy案例陈述应按优先级排序,因为Hart联合评论案例陈述在第一个满足条件时存在。我也在考虑这一点,如果基础数据有一个null而不是0,这将特别方便。我也在想,如果基础数据有一个null而不是0,这将特别方便