У меня есть таблица в SQL Server, в которой есть несколько столбцов, некоторые из них называются ElementID1
, FrameLossCount
и т. д. Я хочу написать запрос, который ищет дубликаты в ElementID1
. Инструкции должны быть такими, чтобы все значения в ElementID1
проверялись, и в случае повторения более одного раза значения FrameLossCount
проверялись и сохранялись только самые большие, а другие строки с точно такими же ElementID1
удалялись.
Я придумал этот код, но хочу проверить, существует ли более простой код (из-за некоторых ограничений другой более короткий код). Спасибо.
WITH RankedDuplicates AS (
SELECT
ElementID1,
FrameLossCount,
ROW_NUMBER() OVER (PARTITION BY ElementID1 ORDER BY FrameLossCount DESC) AS rn
FROM
TableName
)
DELETE FROM TableName
WHERE ElementID1 IN (
SELECT ElementID1
FROM RankedDuplicates
WHERE rn > 1
);
Я попробовал, и мне нужен более короткий и четкий запрос.
MySQL сильно отличается от сервера sql, исправьте теги.
Вероятно, вы можете удалить непосредственно из своего CTE, не используя его в подзапросе.
Хм. опубликованный запрос удалит все элементы elementid1, где есть дубликаты... а это, я думаю, вам не нужно.
Правда, я пропустил кое-что очень важное, а именно дату. Мне нужно только проверять дубликаты каждой даты
Чтобы расширить ответ DaleK, см. эту db<>fiddle.
@user2019455 user2019455 - Если вам нужно выполнить сброс для каждой даты, вы, вероятно, можете просто расширить PARTITION BY
до чего-то вроде PARTITION BY ElementID1, CAST(datetimeColumn AS DATE)
.
Вы можете просто сделать: with RankedDuplicates (...) delete RankedDuplicates where rn > 1
нет необходимости во втором соединении (вероятно), а что насчет CTE, проще просто написать подзапрос
Предполагая, что ваши столбцы дат объявлены как datetime
, вы можете использовать следующие запросы:
Запрос1 с CTE: (dbFiddle1)
WITH cte AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ElementID1, DATE ORDER BY FrameLossCount DESC) AS rn
FROM
yourTableName
)
DELETE FROM cte
WHERE rn > 1;
Query2 с соединениями и подзапросами (dbFiddle2
delete TableName from yourTableName t1
left join
(select max(FrameLossCount) maxFrameLossCount,ElementID1, DATE
from yourTableName
group by ElementID1, DATE
) t2
on t1.ElementID1 = t2.ElementID1 and
t1.date = t2.date and
t1.FrameLossCount = t2.maxFrameLossCount
where t2.maxFrameLossCount is null
как насчет добавления в конце еще одного фрагмента, который также удалит дубликаты?
@user2019455 user2019455 оба запроса удаляют дубликаты? Что вы на самом деле имеете в виду?
Вышеуказанные запросы сами по себе содержат оператор Удалить, который удаляет дубликаты.
Я имел в виду, что, возможно, существуют две (или более) записи, по крайней мере, с двумя одинаковыми точными значениями.
@user2019455 user2019455 да, это определение удаления дубликатов, вы предполагаете, что предоставленные запросы не работают? Возможно, пришло время предоставить минимально воспроизводимый пример, потому что ваш вопрос со временем становится все менее ясным.
Я ищу максимально короткий запрос, который гарантирует, что теперь в этой таблице существуют повторяющиеся строки.
@user2019455 user2019455 почему? Действительно ли количество символов, которые вам нужно набрать, имеет здесь значение?
Зачем вам нужен более короткий и лаконичный запрос? Мне это кажется довольно ясным.