我有一张表格,其中包含我们客户的合约信息。我需要根据合约日期本身将合约到期日汇总到该月的某一天。例如,如果合同日期是01-05-2016,我需要将其四舍五入到2016年10月1日。如果合同日期是2016年11月1日,我需要将其四舍五入到2016年1月20日。最后,如果合同日期是2016年1月21日,我需要将其四舍五入到2016年1月30日。这些汇总日期与我们的结算周期相符,我需要将所有合同都归入其中一个结算周期。所有日期都是DATETIME数据类型。任何帮助将不胜感激。
答案 0 :(得分:2)
也许是这样的?
DECLARE @testData TABLE(TestDate DATE);
INSERT INTO @testData VALUES({d'2016-02-05'}),({d'2016-02-12'}),({d'2016-02-21'});
SELECT TestDate
,CASE WHEN DAY(TestDate) BEtWEEN 1 AND 10 THEN 1
WHEN DAY(TestDate) BEtWEEN 11 AND 20 THEN 2
ELSE 3 END AS BillingCycle
,CASE WHEN DAY(TestDate) BEtWEEN 1 AND 10 THEN CAST(CAST(YEAR(TestDate) AS CHAR(4))+REPLACE(STR(MONTH(TestDate),2),' ','0')+'01' AS DATE)
WHEN DAY(TestDate) BEtWEEN 11 AND 20 THEN CAST(CAST(YEAR(TestDate) AS CHAR(4))+REPLACE(STR(MONTH(TestDate),2),' ','0') +'11' AS DATE)
ELSE CAST(CAST(YEAR(TestDate) AS CHAR(4))+REPLACE(STR(MONTH(TestDate),2),' ','0')+'28' AS DATE) END AS BillingCycleDate
FROM @testData
结果:
TestDate BillingCycle BillingCycleDate
2016-02-05 1 2016-02-01
2016-02-12 2 2016-02-11
2016-02-21 3 2016-02-28
答案 1 :(得分:0)
你会做得更好,以避免从字符串中输出日期。漫长的道路是这样的,虽然我确信它可以缩短和混淆。您没有指定在28日之后如何处理日期:
dateadd(
day,
case day(contract_dt)
when 1 then 9
when 2 then 8
...
when 10 then 0
when 11 then 9
when 12 then 8
...
when 20 then 0
when 21 then 7
when 22 then 6
...
when 28 then 0
when 29 then -1
when 30 then -2
when 31 then -3
end,
contract_dt
)
这是我提到的一种比较紧凑的形式:
dateadd(day, case
when day(contract_dt) <= 20
then 10 - day(contract_dt) % 10
else 28 - day(contract_dt)
end, contract_dt)
编辑:我认为,基于您对其他答案的接受,您希望在异常值的情况下回到第28位,因此我相应地编辑了上述内容。