TSQL案例语句
我有一张这样的桌子: 我如何编写一份案例陈述,以仅提取最新的费率,在本例中为费率14?任何时候利率是0.0000,那么我就需要回到以前的利率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
任何帮助都将不胜感激。完全同意@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,这将特别方便