Как добавить новый столбец, который помечает дубликат столбца на основе значения другого столбца в SQL Server?

Я пытаюсь изменить таблицу, добавив столбец, который может Runner_Name все дубликаты Runner_Name на основе Track_Num . Я пытался с помощью:

SELECT [Track_Num],
       ROW_NUMBER() OVER (PARTITION BY [Track_Num] ORDER BY [Runner_Name]) - 1 As Dup,
       [Runner_Name]
  FROM [runner]

но это не работает, это просто последовательность Runner_Name

Таблица runner которая выглядит следующим образом:

Track_Num     Runner_Name
   1            John
   1            John
   1            Jack
   2            Amy
   2            Mary
   2            John
   3            Josh
   3            Josh
   3            Taylor

Желаемая таблица, которую я надеюсь получить:

Track_Num     Runner_Name    Dup
   1            John          1
   1            John          1
   1            Jack          NULL
   2            Amy           NULL
   2            Mary          NULL
   2            John          NULL
   3            Josh          1
   3            Josh          1
   3            Taylor        NULL

Всего 5 ответов


Возможно, просто оберните оконную функцию sign(nullif( ... ,1))

пример

Select *
      ,Dup = sign(NullIf(sum(1) over (partition by  [Track_Num],[Runner_Name] ) ,1))
 From [runner]

Возвращает

Track_Num   Runner_Name Dup
1   Jack    NULL
1   John    1
1   John    1
2   Amy     NULL
2   John    NULL
2   Mary    NULL
3   Josh    1
3   Josh    1
3   Taylor  NULL

Если я правильно понимаю ваш вопрос, попробуйте

select [Track_Num],
       [Runner_Name],
       Case when Count(1) > 1 then 1 else null end as Dup
from runner
group by [Track_num], [Runner_Name]

Используйте Common Table Expression чтобы определить участников, у которых есть дубликаты:

With cte_dups
As
(
    Select 
        r.Track_Num
        , r.Runner_Name
        , Count(*) As Track_Runner_Count
    From dbo.Runner As r
    Group By 
        r.Track_Num
        , r.Runner_Name
)
Select 
    r.Track_Num
    , r.Runner_Name
    , Iif(c.Track_Runner_Count > 1, 1, Null)
From dbo.Runner As r
    Left Outer Join cte_dups As c
        On c.Track_Num = r.Track_Num
        And c.Runner_Name = r.Runner_Name

Сначала group by Track_Num, Runner_Name чтобы получить счетчик каждой комбинации, а затем присоединиться к таблице:

select 
  r.Track_Num, 
  r.Runner_Name,
  case 
    when g.counter > 1 then 1
    else null
  end Dup 
from runner r inner join ( 
  select Track_Num, Runner_Name, Count(*) counter
  from runner
  group by Track_Num, Runner_Name
) g on g.Track_Num = r.Track_Num and g.Runner_Name = r.Runner_Name

Почему бы не выбрать пятый вариант?

SELECT *, dup=(select 1 from runner 
               where track_num=r.track_num and runner_name=r.runner_name 
               having count(*)>1)
FROM runner r

Этот подход работает без оконных функций или общих табличных выражений,

Посмотреть демо здесь: https://rextester.com/WPLCLP17296

Вот демоверсия с нулевыми значениями - они не помечены как дубликаты: https://rextester.com/AND4821


Есть идеи?

10000