2015-08-19 20 views
5

Điều tôi đang cố gắng làm là chọn khoảng thời gian mà phần còn lại của dữ liệu trong bảng được ổn định dựa trên một cột và kiểm tra có thay đổi trong giá trị cột thứ hai không giai đoạn.Máy chủ SQL - Chọn khoảng thời gian không có thay đổi trong dữ liệu

Bảng:

create table #stable_periods 
(
[Date]    date, 
[Car_Reg]   nvarchar(10), 
[Internal_Damages] int, 
[External_Damages] int 
) 

insert into #stable_periods 
values ('2015-08-19', 'ABC123', 10, 10), 
     ('2015-08-18', 'ABC123', 9, 10), 
     ('2015-08-17', 'ABC123', 8, 9), 
     ('2015-08-16', 'ABC123', 9, 9), 
     ('2015-08-15', 'ABC123', 10, 10), 
     ('2015-08-14', 'ABC123', 10, 10), 
     ('2015-08-19', 'ABC456', 5, 3), 
     ('2015-08-18', 'ABC456', 5, 4), 
     ('2015-08-17', 'ABC456', 8, 4), 
     ('2015-08-16', 'ABC456', 9, 4), 
     ('2015-08-15', 'ABC456', 10, 10), 
     ('2015-01-01', 'ABC123', 1, 1), 
     ('2015-01-01', 'ABC456', NULL, NULL); 

--select * from #stable_periods 
-- Unfortunately I can’t post pictures yet but you get the point of how the table looks like 

Những gì tôi muốn nhận là

Car_Reg \t FromDate \t ToDate \t   External_Damages Have internal damages changed in this period? 
 
ABC123 \t 2015-08-18 \t 2015-08-19 \t 10 \t    Yes 
 
ABC123 \t 2015-08-16 \t 2015-08-17 \t 9 \t    Yes 
 
ABC123 \t 2015-08-14 \t 2015-08-15 \t 10 \t    No 
 
ABC123 \t 2015-01-01 \t 2015-01-01 \t 1 \t    No 
 
ABC456 \t 2015-08-19 \t 2015-08-19 \t 3 \t    No 
 
ABC456 \t 2015-08-16 \t 2015-08-18 \t 4 \t    Yes 
 
ABC456 \t 2015-08-15 \t 2015-08-15 \t 10 \t    No 
 
ABC456 \t 2015-01-01 \t 2015-01-01 \t NULL \t    NULL

Về cơ bản để xây dựng khung thời gian nơi [External_Damages] là hằng số và kiểm tra đã làm [Internal_Damages ] thay đổi trong cùng kỳ (không quan trọng bao nhiêu lần). Tôi dành rất nhiều thời gian để thử nhưng tôi sợ rằng mức độ suy nghĩ trừu tượng của tôi ở mức thấp đến mức thấp ... Sẽ rất tuyệt vời khi thấy bất kỳ đề xuất nào.

Cảm ơn,

Bartosz

Trả lời

5

Tôi tin rằng đây là một hình thức Islands Problem.

Dưới đây là một giải pháp sử dụng ROW_NUMBERGROUP BY:

SQL Fiddle

WITH CTE AS(
    SELECT *, 
     RN = DATEADD(DAY, - ROW_NUMBER() OVER(PARTITION BY Car_reg, External_Damages ORDER BY [Date]), [Date]) 
    FROM #stable_periods 
) 
SELECT 
    Car_Reg, 
    FromDate = MIN([Date]), 
    ToDate = MAX([Date]) , 
    External_Damages, 
    Change = 
      CASE 
       WHEN MAX(External_Damages) IS NULL THEN NULL 
       WHEN COUNT(DISTINCT Internal_Damages) > 1 THEN 'Yes' 
       ELSE 'No' 
      END  
FROM CTE c 
GROUP BY Car_Reg, External_Damages, RN 
ORDER BY Car_Reg, ToDate DESC 
+0

Có bất kỳ tùy chọn nào có thể xử lý ngày mất tích trong tập dữ liệu? Giả sử rằng nếu trong các khoảng thời gian xung quanh [External_Damages] giống nhau, thì chúng sẽ giống nhau trong những ngày còn thiếu và chúng ta có thể tạo một khoảng thời gian dài hơn thay vì vài dấu ngắt có thể gây ra số ngày thiếu trong dữ liệu? –

+0

@BartoszX, tôi đề nghị bạn tạo một câu hỏi mới cho điều đó. –

Các vấn đề liên quan