2012-06-25 40 views
6

請幫助我生成以下查詢,我一直在努力一段時間。讓我們說我有一個簡單的表,一個月號和相關信息是否有在這個特殊的月份查找排名函數重複出現

任何失敗的事件下面的腳本來生成樣本數據:

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 
) 

給出一個「重複失敗的定義「:

當事件發生故障期間的任何6個月至少4個月,然後上個月此類故障是發生‘重複失敗’我的查詢應該返回下面的輸出

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 

其中:在一個月

  • R1 - 一次次的失敗沒有6(4次失敗在過去的6個月)。
  • R2第2個月第7個月重複失敗(最近6個月有4個失敗)。
  • R3月3號重複失敗11號(最近6個月4次失敗)。
在一個月

R1 - 同樣1次的失敗沒有因爲18多次失敗應該再次從一開始當新的反覆失敗發生在過去的6週報告期

首次編號

屢禁不止連續因爲numerated基於其數,我必須採取適當的乘數:

  • 1 repated失敗 - X2
  • 第二次的失敗 - X4
  • 第三次和更多的重複故障-X5。
+0

什麼版本的SQL Server? 2012年與2005-2008年相比具有更多的排名功能。 –

+0

嗨,我們正在使用SQL Server 2008 –

+0

我編輯了你的數據(我認爲)修復它 - 如果我犯了一個錯誤,請進一步編輯 – AakashM

回答

2

我相信這可以改善,但它的工作原理。我們基本上做了兩次 - 第一次建立屢次失敗,第二次建立各種重複失敗的種類種類。請注意,Intermediate2絕對可以取消,爲了清晰起見,我只將其分開。所有的代碼是一個聲明,我的解釋是交錯:

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

在這一點上,我們已經建立了,每個月,無論它是一次次的失敗,通過計算在半年失敗直至幷包括它。

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

現在,我們已經算的數量重複失敗的6個月中到現在

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

所以我們可以說,如果這個月是一個反覆失敗,反覆什麼基數失敗了。

結果:

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) 

性能方面的考慮,將取決於你實際有多少數據。

+0

謝謝你AakashM。工作就像一個魅力 –

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這是一個整潔的解決方案,但不會返回所需的輸出。在18個月裏,有一次失敗,但沒有R4。它應該是R1。這是過去6個月內首次發生重複失敗(13-18) –