假设我每个月有3个时期。
那是
6th day - 15th day
16th day - 25th day
26th day - 5th day (next month)
我想将当前日期四舍五入到最接近的结束时间。
结果应该是这样的:
My Date | Result Date
2017-06-03 | 2017-05-25
2017-06-08 | 2017-06-05
2017-06-15 | 2017-06-05
2017-06-21 | 2017-06-15
2017-06-24 | 2017-06-15
2017-06-25 | 2017-06-15
2017-06-26 | 2017-06-25
2017-06-28 | 2017-06-25
2017-07-01 | 2017-06-25
如何在SQL Server中执行此操作?
我更新了我的要求。我想找到另一种方法,而不是使用CASE ... WHEN ...
子句。我已经用这种方式解决了这个问题。 :)
我只是想知道是否有另一种解决方法。感谢
答案 0 :(得分:1)
你可以使用CASE ... WHEN ...
和DateFromParts(在SQL 2012+中可用)这样
DECLARE @SampleData AS TABLE (DateValue date)
INSERT INTO @SampleData VALUES
('2017-06-03'),('2017-06-08'),('2017-06-15'),('2017-06-21'),
('2017-06-24'),('2017-06-25'),('2017-06-26'),('2017-06-28'),
('2017-07-01' )
SELECT sd.DateValue AS [My date],
CASE
WHEN datepart(day,sd.DateValue) BETWEEN 6 AND 15
THEN DateFromParts(year(sd.DateValue), month(sd.DateValue), 5)
WHEN datepart(day,sd.DateValue) BETWEEN 16 AND 25
THEN DateFromParts(year(sd.DateValue), month(sd.DateValue), 15)
ELSE DateFromParts(year(dateadd(day, - 6, sd.DateValue)), month(dateadd(day, - 6, sd.DateValue)), 25)
END as [Result Date]
FROM @SampleData sd
注意:如果您的日期在26th day - 5th day
,那么dateadd(day, - 6, sd.DateValue)
会准确返回上一期的年份和月份。
答案 1 :(得分:0)
你可以试试这个:
Declare @t table (datevalue date)
insert into @t values ('2017-06-03'),('2017-06-08'),('2017-06-15'),('2017-06-21'),('2017-06-24'),('2017-06-25'),('2017-06-26'),('2017-06-28'),('2017-07-01' )
--2017-06-03 | 2017-05-25
--2017-06-08 | 2017-06-05
--2017-06-15 | 2017-06-05
--2017-06-21 | 2017-06-15
--2017-06-24 | 2017-06-15
--2017-06-25 | 2017-06-15
--2017-06-26 | 2017-06-25
--2017-06-28 | 2017-06-25
--2017-07-01 | 2017-06-25
Select datevalue, cast ( cast( year(datevalue) as varchar(10)) +'/' + cast( month(datevalue) as varchar(10)) + '/26' as date) olddate,
cast ( cast( year(datevalue) as varchar(10)) +'/' + cast( month(datevalue)+1 as varchar(10)) + '/5' as date) newdate,
case
when day(datevalue) between 6 and 15 then '5-' + cast( month(datevalue) as varchar(10)) + '-' + cast( year(datevalue) as varchar(10))
when day(datevalue) between 16 and 25 then '15-' + cast( month(datevalue) as varchar(10)) + '-' + cast( year(datevalue) as varchar(10))
when datevalue between cast ( cast( year(datevalue)-1 as varchar(10)) +'/' + cast( month(datevalue) as varchar(10)) + '/26' as date) and cast ( cast( year(datevalue) as varchar(10)) +'/' + cast( month(datevalue) as varchar(10)) + '/5' as date)
then '25-' + cast( month(datevalue)-1 as varchar(10)) + '-' + cast( year(datevalue) as varchar(10))
else '25-' + cast( month(datevalue) as varchar(10)) + '-' + cast( year(datevalue) as varchar(10))
end
from @t
答案 2 :(得分:0)
这似乎可以解决问题:
declare @t table (MyDate date,Expected date)
insert into @t(MyDate,Expected) values
('20170603','20170525'),
('20170608','20170605'),
('20170615','20170605'),
('20170621','20170615'),
('20170624','20170615'),
('20170625','20170615'),
('20170626','20170625'),
('20170628','20170625'),
('20170701','20170625')
select
t.*,
CASE
WHEN Day25 < MyDate THEN Day25
WHEN Day15 < MyDate THEN Day15
WHEN Day05 < MyDate THEN Day05
ELSE
DATEADD(month,DATEDIFF(month,'20010101',MyDate),'20001225')
END as Actual,
u.*
from
@t t
cross apply
(
select
DATEADD(month,DATEDIFF(month,'20010101',t.MyDate),'20010105') as Day05,
DATEADD(month,DATEDIFF(month,'20010101',t.MyDate),'20010115') as Day15,
DATEADD(month,DATEDIFF(month,'20010101',t.MyDate),'20010125') as Day25
) u
基本上,对于每个日期,我们在同一个月内计算可能的截止日期,然后选择在“我的”日期之前的最新截止日期。
如果这些都不适用,那么我们计算上个月的第25个
结果:
MyDate Expected Actual Day05 Day15 Day25
---------- ---------- ----------------------- ----------------------- ----------------------- -----------------------
2017-06-03 2017-05-25 2017-05-25 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-08 2017-06-05 2017-06-05 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-15 2017-06-05 2017-06-05 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-21 2017-06-15 2017-06-15 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-24 2017-06-15 2017-06-15 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-25 2017-06-15 2017-06-15 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-26 2017-06-25 2017-06-25 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-06-28 2017-06-25 2017-06-25 00:00:00.000 2017-06-05 00:00:00.000 2017-06-15 00:00:00.000 2017-06-25 00:00:00.000
2017-07-01 2017-06-25 2017-06-25 00:00:00.000 2017-07-05 00:00:00.000 2017-07-15 00:00:00.000 2017-07-25 00:00:00.000
(我刚刚在此结果中包含了u
列,因此您可以看到它们是如何制定出来的)
DATEADD
/ DATEDIFF
表达式中使用的常量日期有些随意 - 它们只是被选中,以便它们之间具有特定的关系,以便我们希望将相同的关系应用于{ {1}}。
如果MyDate
是带有时间组件的MyDate
或datetime
,那么您可能还想将其强制转换为datetime2
或以其他方式删除时间组件,然后再使用它在比较中,取决于您的确切要求。