操作方法:特定的复杂分组查询

时间:2016-03-29 04:22:57

标签: sql sql-server sql-server-2008-r2

我不确定我是否重复这个查询,如果是这样,请按照"已回答"查询。而且我不确定这个查询的适当标题是什么。

我的SQL Server 2008 R2中有以下数据

|Date              |Status      |
|------------------|------------|
|29-Mar-2016 07:30 |X           |
|29-Mar-2016 07:31 |Y           |
|29-Mar-2016 07:32 |Y           |
|29-Mar-2016 07:33 |Y           |
|29-Mar-2016 07:34 |Y           |
|29-Mar-2016 07:40 |X           |
|29-Mar-2016 07:43 |Z           |
|29-Mar-2016 07:45 |Z           |

我期待的结果如下

|Start Date        | End Date         |Status     |
|------------------|------------------|-----------|
|29-Mar-2016 07:30 |29-Mar-2016 07:31 |X          |
|29-Mar-2016 07:31 |29-Mar-2016 07:34 |Y          |
|29-Mar-2016 07:40 |29-Mar-2016 07:43 |X          |
|29-Mar-2016 07:43 |29-Mar-2016 07:45 |Z          |

有关SQL查询的任何建议。

1 个答案:

答案 0 :(得分:1)

DECLARE @TEMP AS TABLE(
    [Date] DATETIME,
    [Status] VARCHAR
)

INSERT INTO @TEMP VALUES('29.03.2016 07:30','X')
INSERT INTO @TEMP VALUES('29.03.2016 07:31','Y')
INSERT INTO @TEMP VALUES('29.03.2016 07:32','Y')
INSERT INTO @TEMP VALUES('29.03.2016 07:33','Y')
INSERT INTO @TEMP VALUES('29.03.2016 07:34','Y')
INSERT INTO @TEMP VALUES('29.03.2016 07:40','X')
INSERT INTO @TEMP VALUES('29.03.2016 07:43','Z')
INSERT INTO @TEMP VALUES('29.03.2016 07:45','Z')

SELECT * FROM @TEMP

;WITH TEMP(n,d,s)
AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY [Date]),[Date],[Status]
    FROM @TEMP
), StatePeriods(n,T_n,T_d,T_s,TL_n,TL_d,TL_s,TR_n,TR_d,TR_s)
AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY T.d),T.n,T.d,T.s,TL.n,TL.d,TL.s,TR.n,TR.d,TR.s
    FROM TEMP AS T
    LEFT JOIN TEMP AS TR ON T.n = TR.n-1
    LEFT JOIN TEMP AS TL ON T.n-1 = TL.n
    WHERE T.s <> TR.s OR T.s <> TL.s OR TR.s IS NULL OR TL.s IS NULL
)
SELECT SP1.T_n,SP1.T_d,SP1.T_s,SP1.TL_d,SP1.TL_s,CASE WHEN SP1.T_s = SP3.T_s THEN SP3.TR_d ELSE SP3.T_d END
FROM StatePeriods AS SP1
LEFT JOIN StatePeriods AS SP2 ON SP1.n-1 = SP2.n
LEFT JOIN StatePeriods AS SP3 ON SP1.n+1 = SP3.n
WHERE NOT (SP1.T_s=SP2.T_s AND SP1.TL_s IS NOT NULL AND SP1.TR_s IS NOT NULL)

您可以过滤第一行或最后一行

这是一种资源密集型解决方案。但是你可以使用临时表而不是'WITH'