我正在尝试为报告设置一个数据集,要求在所谓的泳道中显示某些任务,即当重叠2次时,它们会在报告中的2个不同的行上显示,并且不会在视觉上重叠(在同一行)。
到目前为止,我已经对基础知识进行了排序,但是在链条的末端与开头不重叠的情况下,链条会多次重叠会变得复杂。
此外,数据分为不同的类别。我觉得只需要包含一个(频道)来显示该功能。
到目前为止,这是我的代码:
DECLARE @TempTable TABLE
(
StartTime DATETIME
,Duration INT
,Id INT
,Channel INT
)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:30:32', 1827, 261832091, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:34:53', 1686, 265169258, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:44:16', 403, 136756869, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:50:45', 2112, 493664900, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:54:44', 1459, 356826302, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:55:01', 2620, 441592787, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 01:05:32', 546, 62903133, 3)
SELECT Swimlane
,StartTime
,EndTime
,Id
,Channel
FROM (
SELECT CASE WHEN tt.id = tt2.id THEN ROW_NUMBER() OVER (PARTITION BY tt.id, tt2.Channel ORDER BY tt.StartTime, tt2.StartTime, tt2.Channel) ELSE NULL END AS 'Swimlane'
,tt.StartTime
,DATEADD(SECOND, tt.Duration, tt.StartTime) AS 'EndTime'
,tt.Id
,tt.Channel
,tt2.StartTime AS 'StartTime2'
,DATEADD(SECOND, tt2.Duration, tt2.StartTime) AS 'EndTime2'
,tt2.Id AS 'Id2'
,tt2.Channel AS 'Channel2'
FROM @TempTable tt
LEFT JOIN @TempTable tt2 ON tt.StartTime >= tt2.StartTime
AND DATEADD(SECOND, tt.Duration, tt.StartTime) >= tt2.StartTime
AND DATEADD(SECOND, tt2.Duration, tt2.StartTime) >= tt.StartTime
AND tt.Channel = tt2.Channel
) a
WHERE a.Swimlane IS NOT NULL
ORDER BY StartTime
这给出了结果:
Swimlane StartTime EndTime Id Channel
1 2017-10-05 00:30:32 2017-10-05 01:00:59 261832091 2
1 2017-10-05 00:34:53 2017-10-05 01:02:59 265169258 3
2 2017-10-05 00:44:16 2017-10-05 00:50:59 136756869 3
2 2017-10-05 00:50:45 2017-10-05 01:25:57 493664900 2
3 2017-10-05 00:54:44 2017-10-05 01:19:03 356826302 2
2 2017-10-05 00:55:01 2017-10-05 01:38:41 441592787 3
2 2017-10-05 01:05:32 2017-10-05 01:14:38 62903133 3
它完美地适用于此处最后一行与前一行最后一行的位置,因为它只与前一行重叠,而不是前一行。 最后一排应该最后排在泳道1上,因为它是空的,但是如果我把它放到泳道3上,我也很满意。
我希望这是有道理的。这对我来说很有意义,但是我已经坚持了很长一段时间,所以我可能会瞪大一些我应该解释的东西。
这里的所有数据当然只是随机噪音,但我相信这些数据充分显示了我的问题。
答案 0 :(得分:1)
您可以将Swimlane添加到临时表并将其初始化为1.只要发现冲突,您就可以增加它。如果只有3个通道可用,则可以将4转换为null。
部分解决方案
DECLARE @TempTable TABLE
(
StartTime DATETIME
,Duration INT
,Id INT
,Channel INT
,Swimlane tinyint default 1
,EndTime as DATEADD(SECOND, Duration, StartTime)
)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:30:32', 1827, 261832091, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:34:53', 1686, 265169258, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:44:16', 403, 136756869, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:50:45', 2112, 493664900, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:54:44', 1459, 356826302, 2)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 00:55:01', 2620, 441592787, 3)
INSERT INTO @TempTable(StartTime, Duration, Id, Channel)
VALUES('2017-10-05 01:05:32', 546, 62903133, 3)
while 1=1 begin
update conflict
set Swimlane = nullif(conflict.Swimlane+1,4)
FROM @TempTable as booking
inner join @TempTable as conflict
on conflict.Id > booking.Id
and conflict.Channel = booking.Channel
and conflict.Swimlane = booking.Swimlane
and ( conflict.StartTime between booking.StartTime and booking.EndTime
or conflict.EndTime between booking.StartTime and booking.EndTime
or booking.StartTime between conflict.StartTime and conflict.EndTime
or booking.EndTime between conflict.StartTime and conflict.EndTime
)
;
if @@ROWCOUNT <= 0 break;
end
SELECT
Swimlane
, StartTime
, EndTime
, Id
, Channel
from @TempTable
ORDER BY StartTime
;
已知问题
如果发生冲突,则始终会移动更大的ID。在下面的例子中,我们应该在第2道上放置ID 2和4,而不是2&amp; 3(当前解决方案)。
============== id:1 time:1-5 lane:1 correct:1
======= id:2 time:1-3 lane:2 correct:2
======= id:4 time:3-5 lane:3 correct:2
===== id:5 time:1-2 lane:3 correct:3
===== id:3 time:4-5 lane:2 correct:3
==== id:6 time:2-4 lane:null correct:3
如果我们用最早的非冲突预订填充车道,它应该会更好。