2016-03-29 15 views
0

Bu sorgu tekrarladığımdan emin değilim, eğer öyleyse lütfen "Cevaplandırılan" sorgusuna göre bana yol göster. Ve bu sorgu için uygun başlık neyin olacağından emin değilim.Nasıl Yapılır: Belirli karmaşık gruplandırma sorgusu

benim SQL Server aşağıdaki verilere sahip 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   | 

SQL sorgularında

|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   | 

Herhangi bir öneri şöyledir ne bekliyorum sonucu.

+2

yerine geçici tabloları kullanabilirsiniz. Boşluklar ve adalar gibi görünür, ancak gerekli mantık açık değildir. Neden bazen 'bitiş tarihi' başlangıç ​​tarihi ile aynı gruptan alınır ve bazen bir sonraki gruptan alınır? –

+0

@VladimirBaranov Tarih, milisaniye cinsinden yakalanır. "Y" gruplandırılmış verilerin son satırı bitiş tarihi olur ve "X" in gruplandırılmış verilerin başlaması başlangıç ​​tarihi olur. – aioracle

cevap

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) 

Ve ilk ya da son satırın

Bu çok kaynak yoğun bir çözümdür filtre edebilirsiniz. Ancak 'WITH'

+0

Bu çözüm için teşekkür ederiz. Çekicilik gibi çalışır! Bu sorguya zaman çizelgesini de ekledim. Bununla ilgili bir takip sorgum var, yakında yayınlayacağım. – aioracle

İlgili konular