Фильтруйте и сохраняйте самые последние дубликаты - PullRequest
2 голосов
/ 18 марта 2019

Пожалуйста, помогите мне с этим, я застрял и не могу понять, как написать мой запрос.Я работаю с SQL Server 2014.

Таблица A (приблизительно 65 тыс. Строк) CEID = первичный ключ

 CEID     State    Checksum
    1        2          666
    2        2          666
    3        2          666
    4        2          333
    5        2          333
    6        9          333
    7        9          111
    8        9          111
    9        9          741
   10        2          656

Желаемый вывод

 CEID     State    Checksum
    3        2          666
    6        9          333
    8        9          111
    9        9          741
   10        2          656

Я хочу сохранитьстрока с наивысшим CEID, если «состояние» равно для всех дублирующих контрольных сумм.Если состояние отличается, но контрольная сумма равна, я хочу сохранить строку с наивысшим CEID для State = 9.Уникальные строки, такие как CEID 9 и 10, должны быть включены в результат независимо от состояния.

Это объединение возвращает все дубликаты:

SELECT a1.*, a2.*
FROM  tableA a1  
INNER JOIN tableA a2 ON a1.ChecksumI = a2.ChecksumI
                     AND a1.CEID <> a2.CEID  

Я также определил MAX(CEID) для каждой дублируемой контрольной суммы с помощьюэтот запрос

SELECT a.Checksum, a.State, MAX(a.CEID) CEID_MAX ,COUNT(*) cnt
FROM tableA a
GROUP BY a.Checksum, a.State
HAVING COUNT(*) > 1
ORDER BY a.Checksum, a.State

С первым запросом я не могу понять, как SELECT строка с самым высоким CEID на контрольную сумму.

Проблема, с которой я сталкиваюсь в прошломво-первых, я не могу использовать GROUP BY в подзапросах, когда я пытаюсь присоединиться к нему.

1 Ответ

2 голосов
/ 18 марта 2019

Вы можете использовать row_number() с разделением по checksum и заказом по State desc и CEID desc. Обратите внимание, что оба ваших условия могут быть выполнены на ORDER BY State desc, CEID desc

И возьмите первый номер строки

;with 
cte as
(
    select  *, rn = row_number() over (Partition by Checksum order by State desc, CEID desc)
    from    TableA
)
select  *
from    cte
where   rn = 1
order by CEID;
...