2014-12-15 18 views
0

Я использую SQL Server 2012 и имею следующий запрос. Давайте назовем этот запрос, A.SQL Server. Удалить из Select

SELECT a.col, a.fk 
FROM Table1 a 
INNER JOIN (
    select b.col 
    from Table1 b 
    group by b.col 
    having count(*) > 1) 
b on b.col = a.col 

Я хочу удалить только строки, возвращаемые из запроса A, в частности, те строки, которые соответствуют возвращаемый седловины И Fk

Я имею в виду сделать следующее, но это будет только удалите строки, соответствующие столбцу.

delete from Table1 
where col in (
SELECT a.col 
    FROM Table1 a 
    INNER JOIN (
     select b.col 
     from Table1 b 
     group by b.col 
     having count(*) > 1) 
    b on b.col = a.col) 
) 
+0

Определяется ли 'pk' как первичный ключ' Table1'? Если совпадение 'pk' совпадает с совпадением' (pk, fk) '. –

+1

Нет, pk не является основным ключом таблицы1. Я буду редактировать имена столбцов, так что это не путает – user2769810

+1

Все еще запутано, так как 'fk' не используется в фильтре первого запроса. Для любого значения 'col', если оно существует несколько раз в' Table1', каждое значение будет отображаться в первом запросе, независимо от 'fk'. –

ответ

3

Использование delete from Join Синтаксис

delete t1 
from table1 t1 
INNER JOIN (SELECT a.col, a.fk 
      FROM Table1 a 
      INNER JOIN (
         select b.col 
         from Table1 b 
         group by b.col 
         having count(*) > 1) 
         b on b.col = a.col) t2 
ON t1.col1=t2.col1 and t1.fk=t2.fk 
+0

Спасибо, отлично работает – user2769810

0

вы можете объединить седловины и FK поля, чтобы быть еще уникальные поданы извлекать требуемые строки

delete from Table1 
where cast(col as varchar(50))+'//'+cast(fk as varchar(50)) in (
SELECT cast(a.col as varchar(50))+'//'+cast(a.fk as varchar(50)) 
    FROM Table1 a 
    INNER JOIN (
     select b.col 
     from Table1 b 
     group by b.col 
     having count(*) > 1) 
    b on b.col = a.col) 
) 
+0

Это решение отлично поработало, но решение NoDisplayName было более простым. – user2769810

0

Вы можете выразить Query A как это:

SELECT col, fk 
FROM (
    SELECT a.col, a.fk, COUNT(*) OVER (PARTITION BY a.col) AS [count] 
    FROM Table1 a 
) counted 
WHERE [count] > 1 

Это приводит к хорошим способом сделать УДАЛИТЬ с помощью КТР:

;WITH ToDelete AS (
    SELECT a.col, a.fk, COUNT(*) OVER (PARTITION BY a.col) AS [count] 
    FROM Table1 a 
) 
DELETE FROM ToDelete 
WHERE [count] > 1 

Это действительно дает тот же результат, что и ВЕЬЕТЕ в вашем вопросе, хотя.

Если вы хотите удалить все, кроме одной строки с повторяющимся значением Col вы можете использовать что-то вроде этого:

;WITH ToDelete AS (
    SELECT a.col, a.fk 
      , ROW_NUMBER() OVER (PARTITION BY a.col ORDER BY a.fk) AS [occurance] 
    FROM Table1 a 
) 
DELETE FROM ToDelete 
WHERE [occurance] > 1 

Поручения статье будет определять, какая строка сохраняется.