Как обработать пустой столбец в разделе row_number с помощью логики дублирования количества?

#sql #tsql

#sql #tsql

Вопрос:

Как обработать пустой столбец в разделе row_number с помощью логики дублирования количества?

В приведенном ниже запросе ProgramID = 300 дважды будет содержать пустое ProgramName. Хотя есть другие строки записей, которые являются дубликатами, мне придется их игнорировать. Мне придется выбрать только пустое ProgramName, и соответствующий ProgramId, который появляется дважды, должен отображать только один набор записей.

Ожидаемый результат из этих 6 строк вставленных записей будет равен 5 строкам записи. Среди этих 5, 1 строка записи содержит пустое имя программы.

  if object_id('tempdb.dbo.#t') is not null    
drop table #t

 Create table #t
 (
 ProgramId int,
 ProgramName nvarchar(100),
 ProgramStatus nvarchar(100)
 )

 Insert into #t  ( ProgramId,ProgramName, ProgramStatus ) values ( 100, 'Test100', 'TestCompleted' )
 go
 Insert into #t ( ProgramId,ProgramName, ProgramStatus ) values ( 100, 'Test100', 'TestCompleted' )
 go
 Insert into #t ( ProgramId,ProgramName, ProgramStatus ) values ( 200, 'Test200', 'TestCompleted' )
 go
 Insert into #t ( ProgramId,ProgramName, ProgramStatus ) values ( 200, 'Test200', 'TestCompleted' )
 go
 Insert into #t ( ProgramId,ProgramName, ProgramStatus ) values ( 300, '', 'Progress' )
 go
 Insert into #t ( ProgramId,ProgramName, ProgramStatus ) values ( 300, '', 'TestCompleted' )
 go

 select * from #t
  

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

1. Примеры данных и желаемые результаты действительно помогли бы.

2. @GordonLinoff , В приведенном выше запросе .. ожидаемые идентификаторы 100, 200. И для 300 .. только одна строка записи. Каждый идентификатор имеет дублирующуюся строку записи. Однако в 300.. нам нужно выбрать только одну строку записи. Будет ли это возможно

Ответ №1:

На самом деле речь идет не о ROW_NUMBER() как таковом, вопрос, похоже, заключается в написании предложения WHERE ниже по потоку…

 with selector as (
  SELECT * 
   , ROW_NUMBER() OVER (PARTITION BY ProgramName ORDER BY ProgramStatus DESC) as rn
     -- though it would be good to order by something more useful, like timestamp
)
select *
from selector
where rn=1 OR ProgramName != ''
  

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

1. Спасибо @megadest .. я пропустил это условие OR .. что меня очень спасло .. спасибо

Ответ №2:

Поможет ли разбиение вашего запроса на два?

     SELECT
        * 
    FROM
        #t 
    WHERE
        ProgramName <> ''  

    UNION ALL  

    SELECT
        ProgramId,
        ProgramName,
        MAX(ProgramStatus) 
    FROM
        #t 
    WHERE
        ProgramName = '' 
    GROUP BY
        ProgramId,
        ProgramName
  

Это позволяет получить желаемый результат, но я просто выбрал одно из двух ProgramStatuses на основе Max (), возможно, вам придется это изменить