#sql
#sql
Вопрос:
у меня следующая ситуация:
у меня была таблица с уникальным ограничением полей serie_id и user_id, я удалил ее, чтобы попробовать что-то, и теперь у меня есть дублированные строки (т. Е. Две или более строк, где пара user_id И serie_id равны)
при попытке просмотреть дублированные строки я использую это
SELECT t1.id
FROM table_A t1
INNER JOIN table_A t2
ON t1.serie_id = t2.serie_id AND t1.user_id = t2.user_id
WHERE t1.id < t2.id
но в таблице МНОГО данных, поэтому это занимает слишком много времени. Есть ли способ оптимизировать его или ускорить?
отредактировано: теперь я использую этот запрос, чтобы получить все идентификаторы дублированных строк,
SELECT id
FROM table_A a
WHERE EXISTS (SELECT 1
FROM table_A b
WHERE a.user_id = b.user_id AND a.serie_id = b.serie_id
HAVING Count(*) > 1)
Order by id desc
это также занимает много времени, более получаса.
Также я хочу сохранить для каждой дублированной записи исходную, как я могу исключить ее из результатов этого запроса?
Я не могу использовать OVER или NUMBER_ROW, как я видел в других комментариях, моя версия этого не позволяет
Пример данных:
id serie_id user_id
1 100 111
2 100 222
3 100 222
4 58 222
5 100 115
6 100 222
Я хочу удалить первые две строки, соответствующие паре user_id:100 — serie_id= 222
таким образом, результат будет:
id serie_id user_id
1 100 111
4 58 222
5 100 115
6 100 222
Комментарии:
1. Пожалуйста, предоставьте образцы данных, желаемые результаты и соответствующий тег базы данных.
2. Опубликуйте схему таблицы, включая все типы столбцов и индексы. и грамматика: если что-то занимает слишком много времени, вы не хотите «замедлять это»; вы хотите ускорить это .
Ответ №1:
Вы должны определить индекс для полей, которые вы хотите использовать во внутреннем соединении. А также для полей, которые вы хотите использовать в кластерах WHERE.
Вы можете включить «Включить фактическую плоскость выполнения» в SQLServer Managmenet Studio. SQL предлагает вам советы по повышению производительности запросов.
Ответ №2:
Чтобы увидеть повторяющуюся пару, вы можете использовать такой запрос:
SELECT t1.serie_id, t1.user_id, COUNT(*) CNT
FROM table_A t1
GROUP BY t1.serie_id, t1.user_id
HAVING COUNT(*) > 1
И чтобы вернуть фактические строки, сохраните результат во временной таблице и присоедините его к исходной таблице, например:
IF OBJECT_ID('tempdb.dbo.#tmp') IS NOT NULL DROP TABLE #tmp
CREATE TABLE #tmp ( serie_id INT, user_id INT, CNT INT)
INSERT INTO #tmp( serie_id, user_id, CNT )
SELECT t1.serie_id, t1.user_id, COUNT(*) CNT
FROM table_A t1
GROUP BY t1.serie_id, t1.user_id
HAVING COUNT(*) > 1
SELECT t1.*,
FROM table_A t1 INNER JOIN #tmp tmp on tmp.serie_id = t1.serie_id and tmp.user_id = t1.user_id
В любом случае, индекс по serie_id, user_id
столбцам должен помочь.
Комментарии:
1. Я использую это, чтобы вернуть идентификаторы дублированных строк, но я хочу сохранить один из них, удалив остальные ВЫБЕРИТЕ идентификатор ИЗ таблицы_a a, ГДЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ таблицы_a b, ГДЕ a.user_id = b.user_id И a.serie_id = b.serie_id, ИМЕЮЩИЙ Count(*)> 1) Порядок по идентификатору desc
2. У меня уже есть индексы как для serie_id, так и для user_id