2013-12-02 2 views
1

Я хотел бы удалить все строки в таблице, которые имеют уникальное значение в столбце setid. Я могу выбрать их следующим образом:Как удалить строки с уникальным значением?

select * from imagesets as a 
where (select count(*) from imagesets as b where a.setid = b.setid) = 1 

Каков наилучший способ их удалить? Есть ли лучший способ их выбрать?

+0

Вы можете оптимизировать подзапрос, добавив 'LIMIT 2', так как вы больше не интересуетесь результатами. Действие удаления объясняется ниже. –

ответ

3

Я думаю, что следующий будет работать в MySQL:

delete i from imagesets i join 
      (select setid, count(*) as cnt 
      from imagesets 
      group by setid 
      having count(*) = 1 
      ) set1 
      on i.setid = set1.setid; 
+1

В этом случае, скорее всего, вам нужно указать, какую таблицу удалить из явно: 'delete imagesets from imagesets ...' (-1 не мой) – zerkms

+0

@zerkms. , , Да, это отсутствовало в инструкции delete. Не так уверен, что упущение стоило нисходящего потока. Вы можете видеть, как это работает здесь (http://www.sqlfiddle.com/#!2/aceb8/1). –

+0

Я считаю, что это работает и +1 для восстановления баланса :-) – zerkms

0

Это может быть сделано как этот

CREATE TEMPORARY TABLE temp.deletesetids AS 
select setid from imagesets as a 
where (select count(*) from imagesets as b where a.setid = b.setid) = 1; 

DELETE t1 FROM imagesets t1 JOIN temp.deletesetids t2 
WHERE t1.SEtId=t2.SEtId; 

DROP TABLE temp.deletesetids; 

Это потребует у вас есть темп SCHEMA. В противном случае просто используйте ваш текущий выбор сеанса

+0

Если вы использовали временную таблицу - вам не нужно было ее вручную отбрасывать (и не нужно было базы данных temp) – zerkms

+0

zerkms, вам все равно придется отбрасывать стол, хотя это временная таблица. это временно, пока вы не удалите его или сеанс не будет выполнен, как только я прочитал. Попробуйте CREATE TEMPORARY TABLE test AS SELECT 1,2; дважды. Это дало мне таблицу ошибок, которая уже существует. –

+0

моя точка была - если вы не используете ее повторно – zerkms

2
CREATE TEMPORARY TABLE to_delete AS 
    SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1; 

DELETE imagesets FROM imagesets NATURAL JOIN to_delete; 
DROP TABLE to_delete; 

Последняя строка не является обязательной. Временные таблицы автоматически удаляются к концу сеанса.

Aparently это тоже работает:

DELETE imagesets FROM imagesets NATURAL JOIN (SELECT setid FROM imagesets GROUP BY setid HAVING COUNT(*) = 1) singles; 

Несмотря на это, используя SELECT внутри DELETE заявления, как MySQL обрабатывает этот запрос, кажется, не создавать конфликты с блокировкой таблицы. Согласно списку процессов, MySQL автоматически создает временную таблицу при этом. Я не могу сказать howover, что он будет работать для каждой версии MySQL.

+0

'DROP TABLE' может быть избыточным в этом случае, не так ли? – zerkms

+0

Не обязательно, но почему бы и нет ... – Havenard

+0

требуется некоторое время. Поэтому, если вы делаете это явно, ваша программа должна ждать, пока 'DROP' преуспеет. PS: вот почему я сказал «* могу *» - если это не требуется - я не могу придумать веских оснований для этого. – zerkms

Смежные вопросы