我有以下数据(查看):
MSVC C/C++ Runtime library
我使用以下查询来获得我需要的结果,按事件分组并按开始顺序,并且只要小到大,就会变大到小:
Declare @YourTable table ([Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25))
Insert Into @YourTable values
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44:05.000','9/9/16 10:48:08.000','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44:10.000','9/9/16 10:49:40.000','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50:03.000','9/9/16 10:51:04.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51:07.000','4/4/16 13:58:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04:04.000','4/4/16 14:29:00.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51:02.000','4/4/16 14:58:00.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04:06.000','4/4/16 15:29:08.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45:08.000','4-4-16 15:55:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 16:22:08.000','4-4-16 16:40:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 16:50:04.000','4/4/16 16:55:00.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 17:05:02.000','4/4/16 17:20:00.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 17:22:06.000','4/4/16 17:29:08.000','Small'),
('11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04:01.000','4/4/16 16:45:00.000','Big');
我需要再应用一个例外,每当下面的序列出现在一个组的Tag列中时,它应该在较小之后添加aditional行,并且相应地添加starttime,endtime和Tag_new,并且starttime应该比上一个日期晚1秒endtime和endtime比starttime晚1秒,Tag_new为“Bad”:
Select [Event]
,[Start]
,[End]
,[Tag]
,[Tag_new] = case when Tag='Big' and 'Small' = Lead(Tag,1,Tag) over (Partition By Event Order By Start) then 'Small' else tag end
From @YourTable
Event Start End Tag Tag_new
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:44:05.000 2016-09-09 10:48:08.000 Big Big
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:44:10.000 2016-09-09 10:49:40.000 Big Small
10PIC700422.PV 10-PSV-700073A 10-PSV-700073B 2016-09-09 10:50:03.000 2016-09-09 10:51:04.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 12:51:07.000 2016-04-04 13:58:09.000 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 14:04:04.000 2016-04-04 14:29:00.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 14:51:02.000 2016-04-04 14:58:00.000 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 15:04:06.000 2016-04-04 15:29:08.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 15:45:08.000 2016-04-04 15:55:09.000 Big Big
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 16:22:08.000 2016-04-04 16:40:09.000 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 16:50:04.000 2016-04-04 16:55:00.000 Small Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 17:05:02.000 2016-04-04 17:20:00.000 Big Small
11PIC41010.PV 11-PSV-401002A 11-PSV-401002B 2016-04-04 17:22:06.000 2016-04-04 17:29:08.000 Small Small
11PIC41010.PV 11-PSV-401002W 11-PSV-401002D 2016-04-04 16:04:01.000 2016-04-04 16:45:00.000 Big Big
我想得到类似下面的内容:
Small
Big
Small
答案 0 :(得分:1)
这种设计有点气味,但你可能会尝试这样的事情:
您应该避免使用特定于文化的日期时间文字!
Declare @YourTable table ([Event] varchar(100),[Start] DateTime,[End] DateTime, [Tag] varchar(25))
Insert Into @YourTable values
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44:05.000','9/9/16 10:48:08.000','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:44:10.000','9/9/16 10:49:40.000','Big'),
('10PIC700422.PV 10-PSV-700073A 10-PSV-700073B','9/9/16 10:50:03.000','9/9/16 10:51:04.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 12:51:07.000','4/4/16 13:58:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:04:04.000','4/4/16 14:29:00.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 14:51:02.000','4/4/16 14:58:00.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 15:04:06.000','4/4/16 15:29:08.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 15:45:08.000','4-4-16 15:55:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4-4-16 16:22:08.000','4-4-16 16:40:09.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 16:50:04.000','4/4/16 16:55:00.000','Small'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 17:05:02.000','4/4/16 17:20:00.000','Big'),
('11PIC41010.PV 11-PSV-401002A 11-PSV-401002B','4/4/16 17:22:06.000','4/4/16 17:29:08.000','Small'),
('11PIC41010.PV 11-PSV-401002W 11-PSV-401002D','4/4/16 16:04:01.000','4/4/16 16:45:00.000','Big');
- 为您的查询添加正在运行的行号,并为所有0
行添加original
WITH YourQueryEnhanced AS
(
Select [Event]
,[Start]
,[End]
,[Tag]
,[Tag_new] = case when Tag='Big' and 'Small' = Lead(Tag,1,Tag) over (Partition By [Event] Order By Start) then 'Small' else tag end
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS SortInx --You should put a secure ORDER BY here!!!
,0 AS InnerSortInx
From @YourTable
)
- 使用LAG()
检测您的序列。重叠坏序列有一个问题!
,BadMarked AS
(
SELECT *
,CASE WHEN LAG([Tag],1) OVER(Order By SortInx)='Small'
AND LAG([Tag],2) OVER(Order By SortInx)='Big'
AND LAG([Tag],3) OVER(Order By SortInx)='Small' THEN 1 ELSE 0 END AS BadSequence
FROM YourQueryEnhanced
)
- 这将选择所有original
行,并为标记为bad
的每一行添加BadSequence
行。 SortInx设置为prev值,内部sortInx设置为1
,因此ORDER BY
会将bad
行推到适当的位置
SELECT *
FROM BadMarked
UNION ALL
SELECT [Event],[Start],[End],'Bad','Bad',SortInx-1,1,2
FROM BadMarked
WHERE BadMarked.BadSequence=1
ORDER BY SortInx,InnerSortInx
<强>注意强>
这会在结果中添加一个坏行,正如您在预期结果中所述。
原因是你的第3到第7行你有小大小小的大小。中间small
属于两个序列。
你必须通过更多逻辑来解决这个问题(更多调用LAG()
以进一步查看),检测到错误序列,或者将最后一个选择换成另一个CTE
并再次使用LAG()
删除您不想要的错误行。
答案 1 :(得分:1)
WITH YourQueryEnhanced AS
(
Select [Event]
,[Start]
,[End]
,[Tag]
,[Tag_new] = case when Tag='Big' and 'Small' = Lead(Tag,1,Tag) over (Partition By [Event] Order By Start) then 'Small' else tag end
,ROW_NUMBER() OVER(Partition By [Event] Order By Start) AS SortInx --You should put a secure ORDER BY here!!!
,0 AS InnerSortInx
From @YourTable
), BadMarked AS
(
SELECT *
,CASE WHEN LAG([Tag],1) OVER(Order By SortInx)='Small'
AND LAG([Tag],2) OVER(Order By SortInx)='Big'
AND LAG([Tag],3) OVER(Order By SortInx)='Big' THEN 1 ELSE 0 END AS BadSequence
FROM YourQueryEnhanced
)
select * from
(
SELECT *
FROM BadMarked
UNION ALL
SELECT [Event],DATEADD(s, -1, [Start]) [Start], [End],'Bad','Bad',SortInx-1,1,2
FROM BadMarked
WHERE BadMarked.BadSequence=1
) a order by [Event]
,[Start]