图片描绘了一千个单词。因此突出显示的行(很容易解决)是正确的。
但是我想在其他行上做的是将月份连接起来,例如如果我们参考第2行,该行的开始日期和结束日期之间有4个月: “ 1015 1115 1215 0116”
关于如何实现此目标的任何建议?
SQL Server版本是2012。
为澄清起见:
出于这个问题的目的,我们需要专注于两列-StartDate和EndDate。 “ NumberOfColumns”是我创建的一个派生列,其中显示了从开始到结束的总月数。您可以忽略“ PaymentHolidaysTaken”
帮助程序屏幕截图的最后一列以及我要实现的目标是-从StartDate到EndDate(使用空格分隔符)显示每月和每年的MMYY。如上所述,第2行是几个月和几年的一个很好的示例,我希望此值为“ 1015 1115 1215 0116”。第4行应为“ 0916 1016”
这澄清吗?
我不能接受-动态SQL或游标。公司编码标准。
答案 0 :(得分:0)
图片描绘了一千个字
不! Don't post pictures of data or code!
即使有图片,您的问题也不清楚。而且-看我想回答的问题-您知道,我必须输入测试场景。这实际上是您的工作...对于下一个问题,请提供一个有效的独立方案并添加预期的输出。添加您自己尝试的代码和一些说明。这值得一千个单词,图片很烦人……
正如已经告诉我们的:这个问题不是很清楚,所以这可能对您来说是错误的,但是我的魔幻水晶球告诉我,您正在寻找这个:
DECLARE @tbl TABLE(D1 DATE, D2 DATE);
INSERT INTO @tbl VALUES
({d'2016-02-01'},{d'2016-03-31'})
,({d'2015-10-01'},{d'2016-01-31'}) --Your Row 2
,({d'2016-09-01'},{d'2016-10-31'}) --Your Row 4
,({d'2015-12-01'},{d'2015-12-31'})
,({d'2018-04-01'},{d'2018-06-30'})
,({d'2018-04-04'},{d'2018-06-30'}) --Day index != 1, but smaller in D1
,({d'2018-04-04'},{d'2018-06-03'}); --Day index is smaller in D2
SELECT t.*
,A.CountOfMonths
,(
SELECT TOP(A.CountOfMonths) CONCAT(' '
,FORMAT(DATEADD(MONTH,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1,D1),'MMyy')
)
FROM master..spt_values
FOR XML PATH('')
)
FROM @tbl t
CROSS APPLY (SELECT DATEDIFF(MONTH,D1,D2)
+ CASE WHEN DAY(D1)<DAY(D2) THEN 1 ELSE 0 END) A(CountOfMonths);
结果
D1 D2 CoM
2016-02-01 2016-03-31 2 0216 0316
2015-10-01 2016-01-31 4 1015 1115 1215 0116
2016-09-01 2016-10-31 2 0916 1016
2015-12-01 2015-12-31 1 1215
2018-04-01 2018-06-30 3 0418 0518 0618
2018-04-04 2018-06-30 3 0418 0518 0618
2018-04-04 2018-06-03 2 0418 0518
查询将使用一些计算来查找两个日期之间的“ NumberOfMonths”。此值将用于获取表的TOP()
行。我使用的master..spt_values
只是一个有很多行的表。我们对这些值不感兴趣,只是对具有正确行数的结果集不感兴趣。在这个集合上,我应用ROW_NUMBER
得到一个运行编号(1,2或1,2,3,4,依此类推)。这个运行编号以月为单位添加到D1中。最终输出由FORMAT()
完成。
4月4日这一行显示,您的第一个日期并不总是该月的第一天。因此,我添加了第二个月的日索引较小的情况,在“正常”情况下,我使用CASE
再添加一个月。可能是,您希望将其更改为<=
...如果D1和D2中的当天索引相同,我不知道您要怎么做...
如果这不能解决您的问题,请使用我的方案,添加说明性数据,并使用问题的编辑选项从中提出一个好问题...