在具有特定值的其他记录之前添加新行

Adding a new row before other records that have specific value

我有以下 table:

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),它在 State == 0 的每一行之前插入一个新行。新行应该有 DateTime = TheRowOfInterest(datetime) - 1 秒和 State = 1.

TheRowOfInterest 是 State == 0 的每一行。

重要约束:仅当先前记录的状态 == 1 时才应添加新行。

结果 table 如下所示:

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

我知道我需要使用 window-ing 函数,但还没有完成,欢迎提出任何建议。

更多信息:

这是创建语句和示例数据

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)

这是一个非常简单的解决方案。您还没有发布您尝试过的内容,这在发布问题时非常重要;这意味着志愿者知道您已经付出了一些努力,并且您不希望您为他们做他们的工作。

无论如何,正如我所说,这是通过使用 CTE LAGUNION 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 的评论;不要使用关键字作为列名。 statedatetime 都是 SQL 服务器中的关键字。

如果您知道标识值是连续的,那么您可以像这样简单地将 table 与其自身连接起来:

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;

您也可以在此处查看 fiddle

SQL Fiddle