如何在SQL表中的开始日期和结束日期之间拆分月份
我想在SQL Server中设置一个存储过程,它根据每种货币的开始日期和结束日期创建每月的货币汇率 以下是我要使用的表的格式:如何在SQL表中的开始日期和结束日期之间拆分月份,sql,sql-server,database,tsql,Sql,Sql Server,Database,Tsql,我想在SQL Server中设置一个存储过程,它根据每种货币的开始日期和结束日期创建每月的货币汇率 以下是我要使用的表的格式: Table 1 (Input Table) +------------+------------+------------+ | Start Date | End Date | Currency | +------------+------------+------------+ | 01/01/2016 | 30/05/2016 | EUR |
Table 1 (Input Table)
+------------+------------+------------+
| Start Date | End Date | Currency |
+------------+------------+------------+
| 01/01/2016 | 30/05/2016 | EUR |
| 01/03/2017 | 31/05/2017 | BDT |
+------------+------------+------------+
从上表中,我希望存储过程给出如下输出:
Table 2 (Desired result from sql script)
Date Currency
---------------------
01/01/2016 EUR
01/02/2016 EUR
01/03/2016 EUR
01/04/2016 EUR
01/05/2016 EUR
01/03/2017 BDT
01/04/2017 BDT
01/05/2017 BDT
Final Table (Join on Table 1 and 2)
Start Date End Date Split Date Currency Exchange Rate
-------------------------------------------------------------
01/01/2016 30/05/2016 18/01/2016 EUR x
01/01/2016 30/05/2016 18/02/2016 EUR z
01/01/2016 30/05/2016 18/03/2016 EUR h
01/01/2016 30/05/2016 18/04/2016 EUR g
01/01/2016 30/05/2016 18/05/2016 EUR a
01/03/2017 31/05/2018 01/03/2017 BDT b
01/03/2017 31/05/2018 01/04/2017 BDT c
01/03/2017 31/05/2018 01/05/2017 BDT f
declare @StartDate date = '20170401'
, @EndDate date = '20170731';
;with Months as
(
select top (datediff(month, @startdate, @enddate) + 1)
[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate),
MonthEnd = dateadd(day,-1,dateadd(month, row_number() over (order by number), @StartDate))
from
master.dbo.spt_values
order by
[Month]
)
select * from Months;
然后我想将这两个输出连接起来,得到一个最终的表,如下所示:
Table 2 (Desired result from sql script)
Date Currency
---------------------
01/01/2016 EUR
01/02/2016 EUR
01/03/2016 EUR
01/04/2016 EUR
01/05/2016 EUR
01/03/2017 BDT
01/04/2017 BDT
01/05/2017 BDT
Final Table (Join on Table 1 and 2)
Start Date End Date Split Date Currency Exchange Rate
-------------------------------------------------------------
01/01/2016 30/05/2016 18/01/2016 EUR x
01/01/2016 30/05/2016 18/02/2016 EUR z
01/01/2016 30/05/2016 18/03/2016 EUR h
01/01/2016 30/05/2016 18/04/2016 EUR g
01/01/2016 30/05/2016 18/05/2016 EUR a
01/03/2017 31/05/2018 01/03/2017 BDT b
01/03/2017 31/05/2018 01/04/2017 BDT c
01/03/2017 31/05/2018 01/05/2017 BDT f
declare @StartDate date = '20170401'
, @EndDate date = '20170731';
;with Months as
(
select top (datediff(month, @startdate, @enddate) + 1)
[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate),
MonthEnd = dateadd(day,-1,dateadd(month, row_number() over (order by number), @StartDate))
from
master.dbo.spt_values
order by
[Month]
)
select * from Months;
我在stackoverflow上找到了如下解决方案:
Table 2 (Desired result from sql script)
Date Currency
---------------------
01/01/2016 EUR
01/02/2016 EUR
01/03/2016 EUR
01/04/2016 EUR
01/05/2016 EUR
01/03/2017 BDT
01/04/2017 BDT
01/05/2017 BDT
Final Table (Join on Table 1 and 2)
Start Date End Date Split Date Currency Exchange Rate
-------------------------------------------------------------
01/01/2016 30/05/2016 18/01/2016 EUR x
01/01/2016 30/05/2016 18/02/2016 EUR z
01/01/2016 30/05/2016 18/03/2016 EUR h
01/01/2016 30/05/2016 18/04/2016 EUR g
01/01/2016 30/05/2016 18/05/2016 EUR a
01/03/2017 31/05/2018 01/03/2017 BDT b
01/03/2017 31/05/2018 01/04/2017 BDT c
01/03/2017 31/05/2018 01/05/2017 BDT f
declare @StartDate date = '20170401'
, @EndDate date = '20170731';
;with Months as
(
select top (datediff(month, @startdate, @enddate) + 1)
[Month] = dateadd(month, row_number() over (order by number) -1, @StartDate),
MonthEnd = dateadd(day,-1,dateadd(month, row_number() over (order by number), @StartDate))
from
master.dbo.spt_values
order by
[Month]
)
select * from Months;
但是,这只使用硬编码的开始和结束日期。我想从输入表中每行提取开始日期和结束日期,如问题开头所述。我想我已经了解了您要做的事情。这将在一个查询中完成所有操作 首先设置测试数据(更正enddate
;with splits as
(
select *, startdate as split from xchg
union all
select startdate, enddate, currency,
dateadd(m,1,split)
from splits
where dateadd(m,1,split) <= enddate
)
select * from splits order by currency, split
请阅读一些关于改进您的问题的提示。您提供了几个示例数据表,但没有DDL,也没有解释如何将数据从一个表转换到下一个表。我看不出最终结果中使用了中间表。最终结果似乎是第一个表中开始日期和结束日期之间的每天。您在CTE中找到的示例可以很容易地使用源表中的日期,而不是固定日期(如果需要),但我认为这不能回答您的基本问题。此外,您的EUR结束日期早于开始日期。这个问题有很多令人困惑的地方,并且没有足够的信息:1>您能否提供您的输入参与表DDL和一些样本数据,然后提供您想要的输出,而不是提供中间数据的样子?2> 不确定从何处获取ExchangeRate值。3> 您的欧元截止日期似乎比您的起始日期早。请您用这些详细信息编辑问题好吗?4>另外,请您解释一下为什么您的输出拆分日期为每月18欧元,起始日期为2016年1月18日,但对于BDT,尽管起始日期为2017年3月19日,但它是每月1日?非常感谢。这个对我有用。汇率将来自外部来源。我也根据您的反馈更正了拼写错误:)