Sql server 我该如何安排一个约会?
我有一个表,其中包含我们客户的合同信息。我需要根据合同日期将合同到期日四舍五入到每月的某一天。例如,如果合同日期为2016年5月1日,我需要将其四舍五入至2016年10月1日。如果合同日期为2016年11月1日,我需要将其四舍五入至2016年1月20日。最后,如果合同日期为2016年1月21日,我需要将其四舍五入至2016年1月30日。这些汇总日期与我们的计费周期相匹配,我需要我们所有的合同都在其中一个计费周期内。所有日期都是日期时间数据类型。任何帮助都将不胜感激。也许是这样的Sql server 我该如何安排一个约会?,sql-server,date,Sql Server,Date,我有一个表,其中包含我们客户的合同信息。我需要根据合同日期将合同到期日四舍五入到每月的某一天。例如,如果合同日期为2016年5月1日,我需要将其四舍五入至2016年10月1日。如果合同日期为2016年11月1日,我需要将其四舍五入至2016年1月20日。最后,如果合同日期为2016年1月21日,我需要将其四舍五入至2016年1月30日。这些汇总日期与我们的计费周期相匹配,我需要我们所有的合同都在其中一个计费周期内。所有日期都是日期时间数据类型。任何帮助都将不胜感激。也许是这样的 DECLARE
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
避免从字符串中选择日期会更好。漫长的道路是这样的,虽然我相信它可以缩短和模糊。但是,您没有指定如何处理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日,因此我对上述内容进行了相应的编辑。这些是否总是从每月10日开始使用10天的增量?2月的最后一个合同日期是什么?那么2016年2月21日的规则是什么?2/28? 还是2/29?2016年1月31日怎么样?2/10? 听起来是一个制作日历表的好机会。使用DATEADD和DATEDIFF。如何处理2月20日之后的日期?我犯了一个错误。计费周期3始终为每个月的28日。这就是我们避免问题的方法。@user3712737这使问题变得更简单!查看我的编辑!好啊多亏了你的帮助,我的合同日期已经正确了,现在我需要在下一个付款到期日做同样的事情。我的问题是,这是一个计算字段。我创建了一个CTE来计算下一个付款到期日,但当我尝试应用您的修复来对日期进行取整时,从字符串转换日期和/或时间时,转换失败。CTE按如下方式计算下一个付款到期日:cteNextDueDate DocNmbr,NextDueDate为SELECT dbo.RM20101.DOCNUMBR,CONVERT VARCHAR20,DATEADD MONTH,-RM20101.CURTRXAM/CONVERTMONEY,CVS.PmtAmt-1,RM20101.DUEDATE,111作为下一个使用日期,从dbo.RM20101上的dbo.RM20101.DOCNUMBR=dbo.SOP30200.sopnume左外连接dbo.SY90000.ObjectID=SOP30200.sopnume和dbo.SY90000.ObjectType='SalesPaymentTermsEntry'和dbo.SY90000.PropertyName='MonthlyPayments'左外连接CtePayments'作为CVS在dbo.SY90000.ObjectID=CVS.ObjectdCase当DAYDUDT.DocNmbr介于1和10之间时,则CASTCASTYEARDUDT.DocNmbr为CHAR4+替换RmonthDudt.DocNmbr,2',,'0'+'10'为DAYDUDT.DocNmbr介于11和20之间时的日期,然后CASTCASTYEARDUDT.DocNmbr为CHAR4+替换RmonthDudt.DocNmbr,2',',“0'+'20'作为日期,否则castYearDudt.DocNmbr作为CHAR4+REPLACESTRMONTHDUDT.DocNmbr,2',“0'+'28'作为日期结尾作为NextDueDate,@user3712737这就是字符串方法不好的原因。我发现了错误。谢谢大家的帮助!!