CREATE TABLE T1
(Asset_Id int, Trailer_Id int, AssignStart datetime, AssignEnd DATETIME)
;
INSERT INTO T1
(Asset_Id, Trailer_Id, AssignStart, AssignEnd)
VALUES
(37124, 32607, '2018-04-19 08:55:00', '2018-05-05 10:00:00.000'),
(37124, 32607, '2018-05-05 11:23:00', NULL),
(33000, 30000, '2018-04-01 15:00:00', '2018-04-15 10:30:00.000'),
(34000, 31000, '2018-04-05 10:00:00', '2018-04-10 09:30:00.000'),
(34000, 32500, '2018-04-10 09:31:00', NULL),
(37000, 32600, '2018-04-19 08:55:00', '2018-04-25 08:30:00.000'),
(37000, 32600, '2018-04-25 09:23:00', '2018-04-25 10:00:00.000'),
(37000, 32600, '2018-04-25 11:23:00', '2018-04-30 15:00:00.000'),
(37000, 32600, '2018-04-30 16:15:00', '2018-04-30 17:30:00.000'),
(37000, 32600, '2018-05-01 18:23:00', NULL),
(38000, 36000, '2018-05-01 10:00:00', '2018-05-10 06:30:00.000'),
(38000, 36000, '2018-05-15 09:00:00', '2018-05-20 11:00:00.000'),
(38000, 36000, '2018-05-20 12:00:00', NULL),
(33000, 30000, '2018-05-01 10:00:00', NULL)
;
我有以下示例数据 -
Asset_Id Trailer_Id AssignStart AssignEnd
37124 32607 2018-04-19 08:55:00.000 2018-05-05 10:00:00.000
37124 32607 2018-05-05 11:23:00.000 NULL
33000 30000 2018-04-01 15:00:00.000 2018-04-15 10:30:00.000
34000 31000 2018-04-05 10:00:00.000 2018-04-10 09:30:00.000
34000 32500 2018-04-10 09:31:00.000 NULL
37000 32600 2018-04-19 08:55:00.000 2018-04-25 08:30:00.000
37000 32600 2018-04-25 09:23:00.000 2018-04-25 10:00:00.000
37000 32600 2018-04-25 11:23:00.000 2018-04-30 15:00:00.000
37000 32600 2018-04-30 16:15:00 2018-04-30 17:30:00.000
37000 32600 2018-05-01 18:23:00 NULL
38000 36000 2018-05-01 10:00:00.000 2018-05-10 06:30:00.000
38000 36000 2018-05-15 09:00:00.000 2018-05-20 11:00:00.000
38000 36000 2018-05-20 12:00:00.000 NULL
33000 30000 2018-05-01 10:00:00.000 NULL
如您所见,资产和预告片之间的一些分配在同一天结束并再次开始 - 除了最后一行 - 差距和岛屿
示例(1)
Asset_Id Trailer_Id AssignStart AssignEnd
37000 32600 2018-04-19 08:55:00.000 2018-04-25 08:30:00.000
37000 32600 2018-04-25 09:23:00.000 2018-04-25 10:00:00.000
37000 32600 2018-04-25 11:23:00.000 2018-04-30 15:00:00.000
37000 32600 2018-04-30 16:15:00.000 2018-04-30 17:30:00.000
37000 32600 2018-05-01 18:23:00.000 NULL
我期待的这个样本的输出是
Asset_Id Trailer_Id AssignStart AssignEnd
37000 32600 2018-04-19 08:55:00.000 2018-04-30 17:30:00.000
37000 32600 2018-05-01 18:23:00.000 NULL
现在这是另一部分与间隙和岛屿。相同资产和预告片之间的某些分配已结束,然后在将来的某个日期重新开始
示例(2)
Asset_Id Trailer_Id AssignStart AssignEnd
33000 30000 2018-04-01 15:00:00.000 2018-04-15 10:30:00.000
33000 30000 2018-05-01 10:00:00.000 NULL
我期待的这个样本的输出是
Asset_Id Trailer_Id AssignStart AssignEnd
33000 30000 2018-04-01 15:00:00.000 2018-04-15 10:30:00.000
33000 30000 2018-05-01 10:00:00.000 NULL
示例(3)
Asset_Id Trailer_Id AssignStart AssignEnd
38000 36000 2018-05-01 10:00:00.000 2018-05-10 06:30:00.000
38000 36000 2018-05-15 09:00:00.000 2018-05-20 11:00:00.000
38000 36000 2018-05-20 12:00:00.000 NULL
我期待的这个样本的输出是
Asset_Id Trailer_Id AssignStart AssignEnd
38000 36000 2018-05-01 10:00:00.000 2018-05-10 06:30:00.000
38000 36000 2018-05-15 09:00:00.000 NULL
我努力编写将提供以下输出的查询
Asset_Id Trailer_Id AssignStart AssignEnd
37124 32607 2018-04-19 08:55:00.000 NULL
33000 30000 2018-04-01 15:00:00.000 2018-04-15 10:30:00.000
34000 31000 2018-04-05 10:00:00.000 2018-04-10 09:30:00.000
34000 32500 2018-04-10 09:31:00.000 NULL
37000 32600 2018-04-19 08:55:00.000 2018-04-30 17:30:00.000
37000 32600 2018-05-01 18:23:00.000 NULL
38000 36000 2018-05-01 10:00:00.000 2018-05-10 06:30:00.000
38000 36000 2018-05-15 09:00:00.000 NULL
33000 30000 2018-05-01 10:00:00.000 NULL
您可以在 CTE 的帮助下使用递归方法。为此,我添加了一个
Row_Number
so ,以确保它是验证的下一条记录。然后创建递归 CTE...命名
cte
。在这里,字段很重要rn as rn_init
——这是创建记录链的基础。这里处理
NULL
的是 AssignEnd 的情况,也很重要,要计算“记录链”count(rn_init) as c_rn_init
。基于此,稍后对其进行过滤。这如果最终查询。添加了 Row_number ,所以要过滤掉记录,
ORDER BY c_rn_init DESC
输出:
小提琴手
我的想法是从下一条记录中获取 AssignStart 值,并在 [AssignEnd] (当前行)和 AssignStart (下一行)之间进行天差(Step1)
如果是 sql server 2012,我们可以使用 LEAD
如果是 2008 年,我们不能使用 LEAD ,所以使用 OUTER APPLY 来获取记录:
这将给我
AssignStart
下一行的,基于[Asset_Id], [Trailer_Id]
Step2:做那个差异栏:
DATEDIFF(DAY,[AssignEnd],next_AssignStart)
步骤 3:在此列上进行分组,从步骤 2
输出:
ps:添加了Order by,所以我可以更容易地验证。
ps2:因为,
NULL
在MAX中被忽略了,所以我用这个表达式来处理区间的上半部分小提琴手
我介绍了我的 T-SQL 解决方案。
小提琴 SQL Server 2017
问题:
我们需要按 Asset 和 Trailer 划分的重叠日期范围(基本时间单位“天”)打包记录。
解决方案:
打包重叠的日期范围需要 3 个步骤:
第 1 步:确定 GroupStart
第 2 步:确定组
第 3 步:确定打包日期范围
设置:
完整查询:
您可以尝试自加入作为替代方案。
在我的环境中(使用示例数据),它生成的读取次数少于 OUTER APPLY。并制定成本更低的执行计划。但是当我添加不同的索引时,外部应用有时会排在首位。