sql server 中两个日期之间的年份以及每个日期在 sql server 中的开始和结束日期
Posted
技术标签:
【中文标题】sql server 中两个日期之间的年份以及每个日期在 sql server 中的开始和结束日期【英文标题】:years between two dates in sql server with starting and end date of each of them in sql server 【发布时间】:2019-09-18 12:22:30 【问题描述】:我想获取两个日期之间的年份及其开始日期和结束日期。假设如果我输入 startdate 为“07/06/2017”,enddate 输入为“18/09/2019”,我想列出两者之间的年份他们分别的开始和结束日期。请建议我如何实现。
输入表:
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business B Year CommittedTransactionFee 18000 07/06/17 00:00 USD
输出表:
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business B 2019-2020 CommittedTransactionFee 18000 07/06/2019 07/06/2020 USD
Business B 2018-2019 CommittedTransactionFee 18000 07/06/2018 07/06/2019 USD
Business B 2017-2018 CommittedTransactionFee 18000 07/06/2017 07/06/2018 USD
我需要将日期拆分为月份,即如果 BusinessGoal.Period = 'Month',我需要一个查询来根据 BusinessGoal 表中提到的期间拆分日期,并在输入和输出表中给出“年”和“月”。 输入表(BusinessGoal):
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C Year CommittedTransactionFee 18000 05/07/19 00:00:00 19/09/19 00:00:00 USD
输出表(BusinessGoal):
BusinessRefId Period GoalType Amount StartDateUtc EndDateUtc Currency
Business C 2019-07 - 2019-08 CommittedTransactionFee 18000 05/07/2019 00:00:00 05/08/2019 00:00:00 USD
Business C 2019-08 - 2019-09 CommittedTransactionFee 18000 05/08/2019 00:00:00 05/09/2019 00:00:00 USD
Business C 2019-09 - 2019-10 CommittedTransactionFee 18000 05/09/2019 00:00:00 05/10/2019 00:00:00 USD
【问题讨论】:
【参考方案1】:你需要一个数字表,这里我用最简单的一个
select BusinessRefId
, cast(ys.y as varchar(4)) + '-' + cast(ys.y + 1 as varchar(4)) Period
, GoalType, Amount
, dateadd(year, nmbs.n, tbl.StartDateUtc) StartDateUtc
, dateadd(year, nmbs.n + 1,tbl.StartDateUtc) EndDateUtc
, Currency
from
-- your real table here
(values (1, 'year', 'CommittedTransactionFee', 1800, cast('20160607' as date), cast (null as date), 'USD'))
tbl(BusinessRefId, Period, GoalType, Amount, StartDateUtc, EndDateUtc, Currency)
join
-- table of numbers
(values (0),(1),(2) --,..
) nmbs(n)
on dateadd(year, nmbs.n + 1, tbl.StartDateUtc) <= getdate()
cross apply (select Year(tbl.StartDateUtc) + nmbs.n y ) ys
编辑
见fiddle
这是我的查询版本,其中包含更多关于需要哪些行的条件(注意ON
子句中的差异)以及如何计算结束日期。它使用 Soundappan 的 ddl 和数据(扩展),据称这些数据与真实的 ddl 和数据非常接近。
主要思想是相同的,使用数字表。您可能希望在数据库中实例化表以在其他类似查询中使用它。
【讨论】:
busines-s-refid 不是整数,而是一个字符串,当我插入我的真实表时,查询返回 0 行。 我们可以修改这个查询来拆分月份的日期吗? @ShantanuDwivedi,提供表格ddl和样本数据 你能解释一下你在这个查询中做了什么吗? @ShantanuDwivedi,我试试,请问查询具体需要说明什么?【参考方案2】:根据您的查询。检查下面的查询会有所帮助。
declare @BusinessGoal table
(BusinessRefId varchar(50),
Period varchar(50),
GoalType varchar(100),
Amount money,
StartDateUtc datetime,
EndDateUtc datetime,
Currency varchar(10))
insert into @BusinessGoal values
('Business A', 'Year', 'CommittedTransactionFee', 45000, '07/06/19', '00:00', 'USD'),
('Business B', 'Year', 'CommittedTransactionFee', 18000, '07/06/17', '00:00', 'USD'),
('Business E', 'Year', 'CommittedTransactionFee', 5000 , '01/08/2019', '01/04/2019', 'USD')
declare @tbl_year table
(yyyy int,
period varchar(50))
insert @tbl_year values
(2015,'2015-2016'),
(2016,'2016-2017'),
(2017,'2017-2018'),
(2018,'2018-2019'),
(2019,'2019-2020'),
(2020,'2020-2021')
select
a.BusinessRefId,
b.period,
a.GoalType,
a.Amount,
DATEADD(YY,b.yyyy-YEAR(a.StartDateUtc),a.StartDateUtc) as StartDateUtc,
DATEADD(YY,b.yyyy-YEAR(a.StartDateUtc)+1,a.StartDateUtc) as EndDateUtc ,
a.Currency
from @BusinessGoal a
inner join @tbl_year b on b.yyyy >=year(a.StartDateUtc)
where a.Period='Year' and b.yyyy <=YEAR(GETDATE()) order by a.BusinessRefId,b.period
样本输出
BusinessRefId| period | GoalType | Amount | StartDateUtc| EndDateUtc | Currency
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Business A | 2019-2020 | CommittedTransactionFee | 45000 | 06/07/2019 | 06/07/2020 | USD
Business B | 2017-2018 | CommittedTransactionFee | 18000 | 06/07/2017 | 06/07/2018 | USD
Business B | 2018-2019 | CommittedTransactionFee | 18000 | 06/07/2018 | 06/07/2019 | USD
Business B | 2019-2020 | CommittedTransactionFee | 18000 | 06/07/2019 | 06/07/2020 | USD
Business E | 2019-2020 | CommittedTransactionFee | 5000 | 08/01/2019 | 08/01/2020 | USD
【讨论】:
你能帮我把关于 BusinessGoal.Period = 'Month' 和 'Quarter' 的日期分开。我可以在这里或您喜欢的任何地方为您提供示例数据。 Ya ok.. 在这里提供样本数据及其每月和每季度的输出或有问题提及。【参考方案3】:SELECT * FROM YourTableName
WHERE
convert(DATETIME,tbl_Date) BETWEEN Convert(DATETIME,CASE WHEN isnull(@FromDate,'')='' THEN jobMain_JobDate ELSE isnull(@FromDate,'') END)
AND Convert(DATETIME, CASE WHEN isnull(@ToDate,'')='' THEN tbl_Date ELSE isnull(@ToDate,'') END)
你可以试试这个Query...null部分也是Handle..
例如如果您仅输入 FromDate 作为“07/06/2017”,那么它将 给你从结果(“07/06/2017”到最后一个日期)
【讨论】:
【参考方案4】:您可以获取开始和结束日期的年份,然后转换为字符串并连接如下
Declare @startdate as date,
@enddate as date
set @startdate='09-10-2017'
set @enddate='07-12-2019'
select convert(varchar,year(@startdate))+'-'+convert(varchar,year(@enddate)) as Period
【讨论】:
这个拆分不是我在上面问题中提到的那个【参考方案5】:根据样本数据和预期结果,您可以使用DATEADD()
函数和CROSS APPLY
as 得到它
SELECT BusinessRefId,
CONCAT(YEAR(DATEADD(Year, -1, SD)), '-', YEAR(SD)) Period,
GoalType,
Amount,
DATEADD(Year, -1, SD) StartDateUtc,
SD EndDateUtc,
Currency
FROM
(
VALUES
('Business B', 'Year', 'CommittedTransactionFee', 18000, '2017-06-07 00:00:00', NULL, 'USD')
)T(BusinessRefId, Period, GoalType, Amount, StartDateUtc, EndDateUtc, Currency)
CROSS APPLY
(
VALUES
(DATEADD(Year, 1, StartDateUtc)),
(DATEADD(Year, 2, StartDateUtc)),
(DATEADD(Year, 3, StartDateUtc))
) TT(SD)
ORDER BY SD DESC;
返回:
+---------------+-----------+-------------------------+--------+---------------------+---------------------+----------+
| BusinessRefId | Period | GoalType | Amount | StartDateUtc | EndDateUtc | Currency |
+---------------+-----------+-------------------------+--------+---------------------+---------------------+----------+
| Business B | 2019-2020 | CommittedTransactionFee | 18000 | 07/06/2019 00:00:00 | 07/06/2020 00:00:00 | USD |
| Business B | 2018-2019 | CommittedTransactionFee | 18000 | 07/06/2018 00:00:00 | 07/06/2019 00:00:00 | USD |
| Business B | 2017-2018 | CommittedTransactionFee | 18000 | 07/06/2017 00:00:00 | 07/06/2018 00:00:00 | USD |
+---------------+-----------+-------------------------+--------+---------------------+---------------------+----------+
Online Demo
【讨论】:
以上是关于sql server 中两个日期之间的年份以及每个日期在 sql server 中的开始和结束日期的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 2005获取任何年份中任何月份的第一个和最后一个日期