Как запустить Row_Number() с фильтрацией

#sql #tsql #row-number

#sql #tsql #строка-номер

Вопрос:

У меня есть таблица с несколькими строками для каждого «номера обращения». Я хочу выбрать одну строку для каждого номера обращения и присоединить это обратно к другой таблице, поддерживая взаимно однозначное отношение.

Условия для выбора этой строки следующие :

1) Прежде всего, отфильтруйте все строки для каждого номера обращения, у которых есть Stage = Cancelled

2) Если вы найдете Stage = ‘Выполняется’ или ‘Приостановлено’, выберите эту строку. (Только один из этих двух может присутствовать для номера обращения)

3) Если нет (2), то выберите Stage = ‘Завершено’, но для последнего ‘времени остановки’. (Я подумал, что здесь нам, возможно, придется использовать ROW_NUMBER())

Я уже создал запрос для ввода номеров строк и выбора одной строки на основе последнего «времени остановки», но я не могу понять, как добавить туда вышеупомянутые фильтры и условия if-else.

     SELECT  [Case Number],
ROW_NUMBER ( )  
    OVER ( PARTITION BY [Case Number] order by [Stop time] desc )  idx
      ,[Stage]
      ,[Time left]
      ,[SLA definition]
      ,[Elapsed time]
      ,[Elapsed percentage]
      ,[Start time]
      ,[Stop time]
      ,[Has breached]
      ,[Breach time]
      ,[Updated]
      ,[Updated by]
      ,[Created]
      ,[Created by]


  FROM ( select * from [SLA_Data] where Stage != 'Cancelled' )v1
  

Комментарии:

1. Ваш запрос довольно далек от истины, и ваш вопрос было бы легче понять, если бы мы могли увидеть некоторые примеры данных.

2. @TimBiegeleisen — Я опубликовал последний запрос, который мне удалось написать, который удовлетворяет условию номер 1. К сожалению, я не могу опубликовать какие-либо данные, поскольку это конфиденциальные данные.

3. Что ж, возможно, пересмотрите это решение, потому что, кроме полного отсутствия данных, это кажется интересным вопросом.

4. Рассматривали ли вы функцию dense_rank()? ROW_NUMBER предоставит приращение для каждого найденного экземпляра указанного раздела, где, как если бы вы использовали dense_rank() поверх (порядок по порядку задач), вы должны увидеть уникальную добавочную запись для каждого порядка задач.

5. Почему номер обращения отсутствует в вашем операторе select?

Ответ №1:

Из вашего вопроса немного сложно определить, но примерно так я интерпретирую (я не могу получить доступ к SQL, и вы не предоставили достаточно тестовых данных, поэтому не можете их протестировать)

    select * from
    ( 
    SELECT  [Task],...,...,
    ROW_NUMBER ( )      
    OVER ( PARTITION BY Task order by 
        case 
        when Stage in('In Progress' ,'Paused') then 1
        when Stage='Completed' then 2 end,
        [Stop time] desc )  idx
    ) 
    where idx=1
  

Комментарии:

1. Кажется, это работает нормально, я нахожусь в процессе проверки данных. Не могли бы вы, пожалуйста, сказать мне, что ‘1’ и ‘2’ делают после ‘then’ в операторе ‘case’?

2. Они дают вам что-то для упорядочивания. Если это выполняется или приостановлено, то 1, завершено 2. Порядок по этому номеру. Это способ просто превратить ваши экзотические требования к заказу во что-то простое. Если вы все еще не поняли это, вы также можете поместить CASE в аналогичную SELECT инструкцию, чтобы посмотреть, что происходит.

3. Работает ли это в том смысле, что упорядочивается по двум параметрам одновременно? Сначала по этапу, а затем по времени остановки? Это дает мне правильные результаты, но хотелось бы иметь очень четкое представление о том, как это работает.

4. Правильно. Ваш in progress amp; paused также будет иметь вторичную сортировку по времени остановки — я полагаю, это не имеет значения.

5. Это не так! Потрясающе! Однако у меня есть к вам еще один вопрос. Что, если из этих заявок я хочу отфильтровать те, в которых все записи для ‘Start time’ одинаковы. Как мне реализовать это здесь?

Ответ №2:

Приведенный ниже код должен работать при условии, что в приведенной ниже таблице присутствует Case_Number или текущая таблица должна быть объединена с таблицей Case_Number

 create view [dbo].[SLA_View] as select * from (

SELECT * FROM
(
SELECT  [Task]
      ,[Stage]
      ,[Time left]
      ,[SLA definition]
      ,[Elapsed time]
      ,[Elapsed percentage]
      ,[Start time]
      ,[Stop time]
      ,[Has breached]
      ,[Breach time]
      ,[Updated]
      ,[Updated by]
      ,[Created]
      ,[Created by]
FROM
(
/* GETS SINGLE CASE FOR MULTIPLE STAGES */
SELECT *,ROW_NUMBER ( )  OVER ( PARTITION BY Task order by [Stage] desc)  RNK
 FROM [SLA_Data] WHERE [CASE_NUMBER] IN 
(
/* GETS DISTINCT CASE NUMBER WITH STAGE = 'PAUSED' OR 'IN PROGRESS' */
SELECT DISTINCT [CASE_NUMBER]
  FROM [SLA_Data]
  WHERE [Stage] != 'Cancelled'
  AND [Stage] IN ('Paused','In Progess')
  GROUP BY  [CASE_NUMBER]
  HAVING COUNT(*) >= 1
  )
  )Y
  WHERE RNK = 1
)Z
UNION
SELECT [Task]
      ,[Stage]
      ,[Time left]
      ,[SLA definition]
      ,[Elapsed time]
      ,[Elapsed percentage]
      ,[Start time]
      ,[Stop time]
      ,[Has breached]
      ,[Breach time]
      ,[Updated]
      ,[Updated by]
      ,[Created]
      ,[Created by]
      FROM
      (
      SELECT *, ROW_NUMBER ( )  OVER ( PARTITION BY Task order by [start time] desc)  idx
      FROM [SLA_Data]
      WHERE [CASE_NUMBER] NOT IN (
      SELECT DISTINCT [CASE_NUMBER]
  FROM [SLA_Data]
  WHERE [Stage] != 'Cancelled'
  AND [Stage] IN ('Paused','In Progess')
  GROUP BY  [CASE_NUMBER]
  HAVING COUNT(*) > 1
  )
)v1 where idx = 1
)