2012-06-25 14 views
6

Proszę, pomóżcie mi wygenerować następujące zapytanie, z którym borykam się od jakiegoś czasu. Pozwala powiedzieć Mam proste tabeli z liczbą miesięcy oraz informacje, czy były jakieś nieudane wydarzenia w tym konkretnym miesiącuZnajdowanie powtarzających się wystąpień z funkcjami rankingowymi

Poniżej skrypt do generowania danych próbki:

WITH DATA(Month, Success) AS 
(
    SELECT 1, 0 UNION ALL 
    SELECT 2, 0 UNION ALL 
    SELECT 3, 0 UNION ALL 
    SELECT 4, 1 UNION ALL 
    SELECT 5, 1 UNION ALL 
    SELECT 6, 0 UNION ALL 
    SELECT 7, 0 UNION ALL 
    SELECT 8, 1 UNION ALL 
    SELECT 9, 0 UNION ALL 
    SELECT 10, 1 UNION ALL 
    SELECT 11, 0 UNION ALL 
    SELECT 12, 1 UNION ALL 
    SELECT 13, 0 UNION ALL 
    SELECT 14, 1 UNION ALL 
    SELECT 15, 0 UNION ALL 
    SELECT 16, 1 UNION ALL 
    SELECT 17, 0 UNION ALL 
    SELECT 18, 0 
) 

Biorąc pod uwagę definicję „wielokrotnym awarii „:

Gdy nastąpi awaria zdarzenie podczas co najmniej 4 miesięcy w okresie 6 miesięcy potem ostatniego miesiąca z takiej awarii jest«uporczywe zaniechanie»moje zapytanie powinno zwrócić następujący wynik

Month Success RepeatedFailure 
1  0 
2  0 
3  0 
4  1 
5  1 
6  0  R1 
7  0  R2 
8  1 
9  0 
10  1 
11  0  R3 
12  1 
13  0 
14  1 
15  0 
16  1 
17  0 
18  0  R1 

gdzie:

  • R1 -1st powtarzającej w miesiącu nr 6 (4 niepowodzenia w ciągu ostatnich 6 miesięcy).
  • R2 - powtórzono niepowodzenie w miesiącu nr 7 (4 niepowodzenia w ciągu ostatnich 6 miesięcy).
  • Powtarzająca się seria R3 -3 w miesiącu 11 (4 niepowodzenia w ciągu ostatnich 6 miesięcy).

R1 -again 1-cia powtarzane niepowodzenie w miesiącu, ponieważ nie 18 Powtarzające się awarie powinny być numerowane ponownie od początku, gdy wystąpi nowa uporczywe zaniechanie po raz pierwszy w ciągu ostatnich 6 okresów sprawozdawczych

Powtarzające się awarie są numerowane kolejno, ponieważ na podstawie jego numeru muszę zastosować odpowiedniego mnożnika:

  • 1-te powtarzającym niepowodzenie - X2
  • 2-cia uporczywe zaniechanie - X4
  • Trzecie i bardziej powtarzające się niepowodzenie - X5.
+0

Jaką wersję programu SQL Server? Rok 2012 ma dodatkowe funkcje rankingowe w porównaniu do lat 2005-2008. –

+0

Cześć, używamy SQL Server 2008 –

+0

Zmodyfikowałem twoje dane, aby (jak sądzę) je naprawić. Dokonaj dalszej edycji, jeśli popełniłem błąd. – AakashM

Odpowiedz

2

Jestem pewien, że można to poprawić, ale działa. Zasadniczo wykonujemy dwie przebiegi - pierwszą, aby ustalić powtarzające się awarie, a drugą, aby ustalić, jakie jest powtarzające się niepowodzenie. Zauważ, że Intermediate2 z pewnością można zlikwidować, ale oddzieliłem go tylko dla jasności. Cały kod jest jedna instrukcja, moje wyjaśnienie jest przeplatany:

;WITH DATA(Month, Success) AS 
-- assuming your data as defined (with my edit) 
,Intermediate AS 
(
SELECT 
    Month, 
    Success, 
    -- next column for illustration only 
    (SELECT SUM(Success) 
    FROM DATA hist 
    WHERE curr.Month - hist.Month BETWEEN 0 AND 5) 
     AS SuccessesInLastSixMonths, 
    -- next column for illustration only 
    6 - (SELECT SUM(Success) 
    FROM DATA hist 
    WHERE curr.Month - hist.Month BETWEEN 0 AND 5) 
     AS FailuresInLastSixMonths, 
    CASE WHEN 
      (6 - (SELECT SUM(Success) 
        FROM DATA hist 
        WHERE curr.Month - hist.Month BETWEEN 0 AND 5)) 
      >= 4 
      THEN 1 
      ELSE 0 
    END AS IsRepeatedFailure 
FROM DATA curr 
-- No real data until month 6 
WHERE curr.Month > 5 
) 

W tym momencie mamy siedzibę, za każdy miesiąc, czy to powtarzający się brak, licząc awarii w okresie sześciu miesięcy włącznie go.

,Intermediate2 AS 
(
SELECT 
    Month, 
    Success, 
    IsRepeatedFailure, 
    (SELECT SUM(IsRepeatedFailure) 
     FROM Intermediate hist 
     WHERE curr.Month - hist.Month BETWEEN 0 AND 5) 
     AS RepeatedFailuresInLastSixMonths 
FROM Intermediate curr 
) 

Teraz możemy liczyć ilość powtarzane niepowodzeń w okresie sześciu miesięcy, co prowadzi aż do teraz

SELECT 
    Month, 
    Success, 
    CASE IsRepeatedFailure 
     WHEN 1 THEN 'R' + CONVERT(varchar, RepeatedFailuresInLastSixMonths) 
     ELSE '' END 
    AS RepeatedFailureText 
FROM Intermediate2 

więc możemy powiedzieć, czy w tym miesiącu jest powtarzany błąd, co cardinality powtórzony awaria jest.

Wynik:

Month  Success  RepeatedFailureText 
----------- ----------- ------------------------------- 
6   0   R1 
7   0   R2 
8   1   
9   0   
10   1   
11   0   R3 
12   1   
13   0   
14   1   
15   0   
16   1   
17   0   
18   0   R1 

(13 row(s) affected) 

Uwagi dotyczące wydajności będzie zależeć od tego, jak dużo danych, które faktycznie mają.

+0

Dziękuję AakashM. Praca jest jak wdzięk –

2
;WITH DATA(Month, Success) AS 
(
    SELECT 1, 0 UNION ALL 
    SELECT 2, 0 UNION ALL 
    SELECT 3, 0 UNION ALL 
    SELECT 4, 1 UNION ALL 
    SELECT 5, 1 UNION ALL 
    SELECT 6, 0 UNION ALL 
    SELECT 7, 0 UNION ALL 
    SELECT 8, 1 UNION ALL 
    SELECT 9, 0 UNION ALL 
    SELECT 10, 1 UNION ALL 
    SELECT 11, 0 UNION ALL 
    SELECT 12, 1 UNION ALL 
    SELECT 13, 0 UNION ALL 
    SELECT 14, 1 UNION ALL 
    SELECT 15, 0 UNION ALL 
    SELECT 16, 1 UNION ALL 
    SELECT 17, 0 UNION ALL 
    SELECT 18, 0 
) 

SELECT DATA.Month,DATA.Success,Isnull(convert(Varchar(10),b.result),'') +   
Isnull(CONVERT(varchar(10),b.num),'') RepeatedFailure 
FROM (
SELECT *, ROW_NUMBER() over (order by Month) num FROM 
(Select * ,(case when (select sum(Success) 
from DATA where MONTH>(o.MONTH-6) and MONTH<=(o.MONTH) ) <= 2 
and o.MONTH>=6 then 'R' else '' end) result 
from DATA o 
) a where result='R' 
) b 
right join DATA on DATA.Month = b.Month 
order by DATA.Month 
+0

Asif to fajne rozwiązanie, ale nie zwraca pożądanej wydajności. W 18 miesiącu następuje ponowna porażka, ale nie R4. Powinien to być R1. Jest to pierwsze wystąpienie powtarzającego się błędu w ciągu ostatnich 6 miesięcy (13-18) –

Powiązane problemy