我有下表:
Id | DateTime | State
1 | 2018-07-16 10:00:00 | 0
2 | 2018-07-16 10:15:34 | 1
3 | 2018-07-16 10:21:12 | 0
4 | 2018-07-16 10:32:45 | 1
5 | 2018-07-16 10:44:05 | 0
我需要一个查询(t-sql),在状态== 0的每一行之前插入新行。新行应具有DateTime = TheRowOfInterest(datetime)-1秒和State = 1。
TheRowOfInterest是状态== 0的每一行。
重要约束:仅当前一条记录的State == 1时,才应添加新行。
结果表如下:
DateTime | State
2018-07-16 10:00:00 | 0
2018-07-16 10:15:34 | 1
2018-07-16 10:21:11 | 1 <<<
2018-07-16 10:21:12 | 0
2018-07-16 10:32:45 | 1
2018-07-16 10:44:04 | 1 <<<
2018-07-16 10:44:05 | 0
我知道我需要使用开窗功能,但还没走太远,因此欢迎提出任何建议。
更多信息:
这是Create语句和示例数据
CREATE TABLE [dbo].[SwitchSeries](
[Id] [int] NOT NULL,
[DateTime] [datetime2](7) NOT NULL,
[State] [tinyint] NOT NULL
)
已填充示例数据:
INSERT INTO SwitchSeries VALUES
(1, '2018-07-16 10:00:00', 0),
(2, '2018-07-16 10:15:34', 1),
(3, '2018-07-16 10:21:12', 0),
(4, '2018-07-16 10:32:45', 1),
(5, '2018-07-16 10:44:05', 0)
答案 0 :(得分:1)
这是一个非常简单的解决方案。您尚未发布您尝试过的内容,这在发布问题时非常重要;这意味着志愿者知道您已经付出了很多努力,并且不希望您为他们做他们的工作。
无论如何,正如我所说,这是通过使用CTE,LAG
和UNION ALL
来实现的:
WITH CTE AS(
SELECT *,
LAG([State]) OVER (ORDER BY [datetime] ASC) AS PreviousState
FROM dbo.SwitchSeries)
SELECT [DateTime], [State]
FROM CTE
UNION ALL
SELECT DATEADD(SECOND,-1,[DateTime]), 1
FROM CTE
WHERE [State] = 0
AND PreviousState = 1
ORDER BY [DateTime];
但是,我完全同意WhatsThePoint的评论;不要使用关键字作为列名。 state
和datetime
都是SQL Server中的关键字。
答案 1 :(得分:1)
如果您知道标识值是连续的,则可以像这样将表本身与表连接起来:
select DateAdd(ss, -1, s2.DateTime), 1
from SwitchSeries s1 inner join SwitchSeries s2 on s1.Id = s2.Id - 1
where s1.State = 1 and s2.State = 0;
您也可以在这里查看小提琴