Удаление не более одной записи для каждой уникальной комбинации кортежей - PullRequest
2 голосов
/ 26 августа 2011

Я хочу удалить не более одной записи для каждого уникального (columnA, columnB) -типа в моем следующем операторе удаления:

DELETE FROM tableA
WHERE columnA IN 
    (
    --some subqueryA
    )
AND columnB IN
    (
    --some subqueryB
    )

Как это достигается? Пожалуйста, учитывайте только те операторы, которые работают при использовании против MSS 2000 (т. Е. Синтаксис T-SQL 2000). Я могу сделать это с помощью итерации по искушаемому, но я хочу написать это, используя только наборы.

Пример:

subqueryA returns 1
subqueryB returns 2,3

Если исходная таблица содержала (столбец A, столбец B, столбец C)

5,2,5
1,2,34
1,2,45
1,3,86

Тогда

1,2,34
1,3,86 

следует удалить. Каждый уникальный (columnA, columnB) -туплет будет отображаться не более двух раз в таблице A, и каждый раз, когда я запускаю свой оператор SQL, я хочу удалить не более одной из этих уникальных комбинаций, а не две.

Если существует одна запись для данного уникального (columnA, columnB) -tuple, удали это.

Если для данного уникального есть две записи (столбец А, columnB) - кортеж, удалите только один из них.

Delete tabA
from  TableA tabA 
Where tabA.columnC in (
      select  max(tabAA.columnC)  from TableA tabAA
      where tabAA.columnA in (1)
      and tabAA.columnB in (2,3)
      group by tabAA.columnA,tabAA.columnB
)

1 Ответ

1 голос
/ 26 августа 2011

Как часто вы собираетесь запускать это, что имеет значение, используете ли вы временные таблицы или нет? Может быть, вам стоит подумать о добавлении ограничений в таблицу, чтобы сделать это только один раз ...

При этом, честно говоря, лучший способ сделать это для SQL Server 2000 - это, вероятно, использовать таблицу #temp, как вы уже делаете. Если вы пытаетесь удалить все, кроме одного, из каждой пары, то вы можете сделать что-то вроде:

  • вставить отдельные строки в отдельную таблицу
  • удалить все строки из старой таблицы
  • переместить отдельные строки обратно в исходную таблицу

Я также сделал такие вещи, как копирование отдельных строк в новую таблицу, удаление старой таблицы и переименование новой таблицы.

Но это не похоже на цель. Можете ли вы показать код, который вы сейчас используете, с таблицей #temp? Я пытаюсь представить, как вы идентифицируете строки, которые нужно сохранить, и, возможно, просмотр вашего существующего кода вызовет что-то.

РЕДАКТИРОВАТЬ - теперь с более понятными требованиями я могу предложить следующий запрос. Пожалуйста, сначала проверьте копию таблицы!

DELETE a 
FROM dbo.TableA AS a
INNER JOIN 
(
   SELECT columnA, columnB, columnC = MIN(columnC) 
      FROM dbo.TableA
      WHERE columnA IN
      (
        -- some subqueryA
        SELECT 1
      )
      AND columnB IN 
      (
        -- some subqueryB
        SELECT 2 UNION SELECT 3
      )
      GROUP BY columnA, columnB
) AS x
ON  a.columnA = x.columnA
AND a.columnB = x.columnB
AND a.columnC = x.columnC;

Обратите внимание, что это не подтверждает, что есть ровно одна или две строки, которые соответствуют группировке в столбце A и столбце B. Также обратите внимание, что если вы запустите это дважды, он удалит оставшуюся строку, которая все еще соответствует подзапросу!

...