sql удалить строки с 1 дублированным столбцом - PullRequest
0 голосов
/ 30 октября 2009

У меня есть таблица microsoft sql 2005 db, в которой вся строка не дублируется, а столбец дублируется.

1 ааа
1 bbb
1 куб. См
2 abc
2 def

Как я могу удалить все строки, кроме 1, в которых дублируется первый столбец?

Для уточнения мне нужно избавиться от второго, третьего и пятого рядов.

Ответы [ 6 ]

9 голосов
/ 30 октября 2009

Попробуйте следующий запрос в SQL Server 2005

WITH T AS (SELECT ROW_NUMBER()OVER(PARTITION BY id ORDER BY id) AS rnum,* FROM dbo.Table_1)
DELETE FROM T WHERE rnum>1
2 голосов
/ 30 октября 2009

Давайте назовем их столбцами id и Col1.

DELETE myTable T1
WHERE EXISTS
  (SELECT * FROM myTable T2
   WHERE T2.id = T1.id AND T2.Col1 > T1.Col1)     

Редактировать: Как отмечает Андомар, вышеизложенное не избавляет от точных повторяющихся случаев, когда и id, и Col1 одинаковы в разных строках. Они могут быть обработаны следующим образом:

(примечание: при этом приведенный выше запрос универсальный SQL , к MSSQL 2005 и выше применяется следующее)
Он использует функцию Общее табличное выражение (CTE) вместе с функцией ROW_NUMBER () для создания отличительного значения строки. По сути, это та же конструкция, что и выше, за исключением того, что теперь она работает с «таблицей» (CTE в основном похожи на таблицу), которая имеет действительно отличный ключ идентификатора.
Обратите внимание, что, удалив «AND T2.Col1 = T1.Col1», мы создадим запрос, который может обрабатывать оба типа дубликатов (дубликаты только с идентификатором и дубликаты как Id, так и Col1) в одном запросе, то есть аналогично тому, как это делал Хамадри. решение (PARTITION в его / ее CTE служит той же цели, что и подзапрос в этом решении, по сути, выполняется тот же объем работы). В зависимости от ситуации, может быть предпочтительным, с точки зрения производительности или иным образом, обрабатывать ситуацию в два этапа.

WITH T AS
  (SELECT ROW_NUMBER() OVER (ORDER BY id, Col1) AS rn, id, Col1 FROM MyTable)
DELETE T AS T1
WHERE EXISTS
   (SELECT * 
    FROM T AS T2
    WHERE T2.id = T1.id AND T2.Col1 = T1.Col1
      AND T2.rn > T1.rn
   )   
1 голос
/ 30 октября 2009
DELETE tableName as ta
WHERE col2 NOT IN (SELECT MIN(col2) FROM tableName AS t2 GROUP BY col1)

Убедитесь, что вспомогательный выбор возвращает строки, которые вы хотите сохранить.

0 голосов
/ 02 октября 2011

- Еще одна идея с использованием ROW_NUMBER ()

Delete MyTable
Where Id IN
(
    Select T.Id FROM
    (
        SELECT ROW_NUMBER() OVER (PARTITION BY UniqueColumn ORDER BY Id) AS RowNumber FROM MyTable
    )T
    WHERE T.RowNumber > 1
)
0 голосов
/ 30 октября 2009

SQL-сервер не является моей собственной базой данных SQL, но может быть что-то вроде этого? Идея состоит в том, чтобы получить дубликаты и удалить их с большим ROW_NUMBER. Это должен оставить только первый. Я не знаю, если это то, что вы хотите, или это сработает, но логика кажется здравой

DELETE T1
FROM T1 T2
WHERE T1.Col1 = T2.col1
AND T1.ROW_NUMBER() > T2.ROW_NUMBER()

Пожалуйста, не стесняйтесь исправлять меня, если SQL-сервер не может справиться с такой обработкой:)

0 голосов
/ 30 октября 2009

Попробуйте это.

DELETE FROM <TABLE_NAME_HERE> WHERE <SECOND_COLUMN_NAME_HERE> IN ("bbb","abc","def");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...