2012-06-25 1 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 
) 

Учитывая определение «неоднократного отказа «:

Когда неудача события происходит в течение не менее 4 месяцев в любых 6 месяцев, то в прошлом месяце с таким несоответствием является„повторным нарушением“мой запрос должен возвращать следующий вывод

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 -1st повторил сбой в месяц нет 6 (4 неудачи в последние 6 месяцев).
  • R2 -2-я повторная неудача в месяце № 7 (4 сбоя за последние 6 месяцев).
  • R3 -3-й повторный отказ в месяце № 11 (4 отказа за последние 6 месяцев). не

R1 -Снова первый повторил сбой в месяц не 18, потому что Повторные Неудачи должны быть снова пронумерованы с самого начала, когда новый неоднократный отказ происходит в первый раз за последние 6 отчетных периодов

Повторные Неудачи нумеруются последовательно, потому что основанный на его номер я должен применять соответствующий множитель:

  • первый repated провал - X2
  • второй повторил отказ - Х4
  • Третий и более повторный отказ -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 
) 

Теперь мы подсчитывали число повторил неудач в течение шести месяцев, предшествовавших до сих пор

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