T-SQL Group несколькими партиями по 2 - PullRequest
0 голосов
/ 18 сентября 2018

Итак, замечательные люди, работающие над stackoverflow, помогли мне с запросом типа «найти последовательные сбои».(Статус = 4 - сбой).Я думал, что справился со второй частью своей проблемы, потому что мой тестовый пример, кажется, работает нормально, но всякий раз, когда я запускаю его в нашей тестовой среде, я получаю хитрые результаты, поэтому я, должно быть, делаю что-то не так.Цель состоит в том, чтобы найти X количество последовательных сбоев.Таким образом, ниже установлено, чтобы найти 2 последовательных сбоев.Я использую SQL Server 2008 R2

DECLARE @t TABLE (
[InstructionId] INT,
[InstructionDetailId] INT,
[Sequence] INT,
[Status] INT
) 
INSERT INTO @t SELECT 222,111,1, 2
INSERT INTO @t SELECT 222,112,2,2
INSERT INTO @t SELECT 222,113,3,4
INSERT INTO @t SELECT 222,114,4,4
INSERT INTO @t SELECT 222,115,5,2
INSERT INTO @t SELECT 222,116,6,4
INSERT INTO @t SELECT 222,117,7,2
INSERT INTO @t SELECT 222,118,8,4
INSERT INTO @t SELECT 222,119,9,4
INSERT INTO @t SELECT 222,120,10,2
INSERT INTO @t SELECT 222,121,11,2
INSERT INTO @t SELECT 222,124,12,4
INSERT INTO @t SELECT 222,126,13,4
INSERT INTO @t SELECT 222,128,14,4

INSERT INTO @t SELECT 223,126,13,4
INSERT INTO @t SELECT 223,128,14,4
INSERT INTO @t SELECT 223,129,15,2
INSERT INTO @t SELECT 223,130,16,4

INSERT INTO @t SELECT 224,111,17,4
INSERT INTO @t SELECT 224,112,18,4

INSERT INTO @t SELECT 223,160,33,4
INSERT INTO @t SELECT 223,161,34,4
INSERT INTO @t SELECT 223,162,35,4
INSERT INTO @t SELECT 223,163,40,4


;with HardcoreCTE AS
(
 select t.*,
  t.[Sequence] - ROW_NUMBER() OVER(PARTITION BY t.instructionId ORDER BY 
  t.InstructionDetailId) AS ItemCount
  from @t t outer apply
    ( select top (1) t1.*
      from @t t1
         where t1.InstructionId = t.InstructionId and
         t1.Sequence < t.Sequence
   order by t1.Sequence desc
 ) t1 outer apply
 ( select top (1) t2.*
   from @t t2
   where t2.InstructionId = t.InstructionId and
         t2.Sequence > t.Sequence
   order by t2.Sequence 
 ) t2
where t.status = 4 and (t.status = t1.status or t.status = t2.status)
)
,

HardCoreCTE2
 AS
 (
 select *, Count(1) OVER(PARTITION BY ItemCount) AS ItemCount2 from 
 HardcoreCTE
 )

 select * from HardCoreCTE2
 where ItemCount2 =2

Таким образом, вышеприведенное работает блестяще, чтобы найти результаты, в которых есть только 2 последовательных сбоя с этими

результатами:

enter image description here

Теперь из приведенных выше результатов он находит только записи, в которых есть 2 последовательных сбоев, но всякий раз, когда я преобразую вышеуказанное в фактическую среду тестированиятаблицы это не похоже на работу.

Результаты теста Env: Как вы можете видеть для "InstructionId" 2518380, он вернул одну запись, а для "InstructionId" 2614351. Он предназначен для возврата наборов из 2 записей.

enter image description here

Test Env Query: (в значительной степени идентичный)

;with InitialDataCTE
AS
(
   SELECT Instruction.InstructionID,InstructionDetail.InstructionDetailID, 
   InstructionDetail.InstructionDetailStatusID AS [Status],
   InstructionDetail.Sequence
   FROM     Instruction INNER JOIN
              InstructionDetail ON Instruction.InstructionID = 
   InstructionDetail.InstructionID

              where InstructionDetailStatusID =4
              and InstructionDetail.PaymentDateOriginal between '2015-01-05' 
       AND '2018-09-08'
  ),
  HardCoreCTE
  AS
  (
select t.*,
t.Sequence - ROW_NUMBER() OVER(PARTITION BY t.instructionId ORDER BY 
t.InstructionDetailId) AS ItemCount
from InitialDataCTE t outer apply
 ( select top (1) t1.*
   from InitialDataCTE t1
   where t1.InstructionId = t.InstructionID and
         t1.Sequence < t.Sequence
   order by t1.Sequence desc
 ) t1 outer apply
 ( select top (1) t2.*
   from InitialDataCTE t2
   where t2.InstructionId = t.InstructionId and
         t2.Sequence > t.Sequence
   order by t2.Sequence 
 ) t2
where t.Status = 4 and (t.Status = t1.Status or t.Status = t2.Status)
)
,
 HardCoreCTE2
 AS
 (
 select *, Count(1) OVER(PARTITION BY ItemCount) AS ItemCount2 from 
 HardCoreCTE
 )
 select * from HardCoreCTE2
 where ItemCount2 =2
 order by InstructionID, Sequence

Действительно признателен, если кто-то может сказать мне, где я иду не так, я былвозиться с вариациями графа (*), но пока ничего успешного.Большое спасибо

1 Ответ

0 голосов
/ 18 сентября 2018

Я пришел к следующему запросу:

with
  a as (
    select *,
      row_number() over(partition by InstructionId order by Sequence)-
      row_number() over(partition by InstructionId, [Status] order by Sequence) g
    from @t
  ),
  b as (
    select *,
      count(*) over(partition by InstructionId, [Status], g) c
    from a
    where [Status] = 4
  )
select *
from b
where c > 2
order by 1, 3;

Для ваших тестовых данных я получил следующий результат:

InstructionId   InstructionDetailId Sequence    Status  g   c
222             224                 312         4       6   3
222             226                 413         4       6   3
222             228                 514         4       6   3
223             161                 84          4       2   3
223             162                 95          4       2   3
223             163                 140         4       2   3

Вы можете проверить этот запрос здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...