Видаліть рядки sql, де ідентифікатори не мають збігу з іншої таблиці


160

Я намагаюся видалити записи-сироти в таблиці mysql.

У мене є 2 таких таблиці:

Таблиця files:

| id | ....
------------
| 1  | ....
| 2  | ....
| 7  | ....
| 9  | ....

стіл blob:

| fileid | ....
------------
| 1  | ....
| 2  | ....
| 3  | ....
| 4  | ....
| 4  | ....
| 4  | ....
| 9  | ....

fileidІ idстовпці можуть бути використані для об'єднання таблиць разом.

Я хочу видалити всі рядки з таблиці, blobде fileidїх не можна знайти в таблиці files.id.

Отже, використовуючи приклад вище, який видалить рядки: 3 та 4 (и) у blobтаблиці.


1
Перейдіть до другої відповіді, якщо ви використовуєте nulls.
Пейс’єр

Відповіді:


327

Використання лівого приєднання / є нульовим:

DELETE b FROM BLOB b 
  LEFT JOIN FILES f ON f.id = b.fileid 
      WHERE f.id IS NULL

Використання НЕ Є:

DELETE FROM BLOB 
 WHERE NOT EXISTS(SELECT NULL
                    FROM FILES f
                   WHERE f.id = fileid)

Використання NOT IN:

DELETE FROM BLOB
 WHERE fileid NOT IN (SELECT f.id 
                        FROM FILES f)

Увага

Коли це можливо, виконайте DELETE в рамках транзакції (якщо підтримувати - IE: Не в MyISAM), щоб ви могли скористатися відкатом, щоб повернути зміни в разі проблем.


12
що, загалом, найшвидше з вищезазначеного?
Hampus Brynolf

2
Чомусь видалення за допомогою кнопки LEFT JOIN не працювало на MS SQL Server Mgmt Studio (не впевнений, чому; він просто поскаржився на НАЛЯГЛИЙ ПРИЄДНАЙТЕСЬ). Хтось знає, чому це? Це працювало з використанням НЕ ІСНУЮ :)
Анна

5
FYI, ось корисне обговорення відносної ефективності цих трьох методів: explainextended.com/2009/09/18 / ...
Зомбі

2
@Pacerier - "неправильно" трохи сильно. Щоб переконатись, що люди розуміють, відповіді діють, якщо fileidвони не замінюються . Крім того, третє рішення ( NOT IN) вимагає лише того f.id, що не зводиться до нуля. Імовірно, це первинний ключ, так би і було.
ToolmakerSteve

2
Для людей, які намагаються
скористатися програмою

26
DELETE FROM blob 
WHERE fileid NOT IN 
       (SELECT id 
        FROM files 
        WHERE id is NOT NULL/*This line is unlikely to be needed 
                               but using NOT IN...*/
      )

Що таке "/ * Цей рядок навряд чи знадобиться, але, мабуть, означає використання NOT IN ... * /" ?
Pacerier

1
@Pacerier - NOT IN (NULL)повертає порожній набір результатів, тому NULL повинні бути виключені. Але idстовпець, мабуть, не буде нульовим так чи інакше, "навряд чи знадобиться"
Мартін Сміт

Нічого хорошого улову. Тож відповідь омпоні невірна! not in(null)досить логічно, чому це не працює? Що обґрунтовує це?
Pacerier


1
@bunkerdive Потім використовуйте три назви об’єктів частини, що містять ім’я бази даних.
Мартін Сміт

17
DELETE FROM blob
WHERE NOT EXISTS (
    SELECT *
    FROM files
    WHERE id=blob.id
)

1
Я думаю, що є files.idі blob.fileid. Я здогадуюсь, що ваш запит призведе до помилки.
jww

-8
delete from table1 t1 
    WHERE not exists (select id from table2 where related_field_in_t2=t1.id) 
    AND not exists (select id from table3 where related_field_in_t3=t1.id) 
    AND not exists (select id from table4 where related_field_t4=t1.id) 
    AND not exists (select id from table5 where related_field_t5=t1.id);

3
Я спростував, тому що: 1. Це не намагається відповісти на питання в контексті, який був розміщений. 2. Немає пояснень (а відповіді лише для коду мають низьке значення для Stackoverflow). 3. NOT EXISTSбуло вже розміщено 9 років тому. 4. Ви не просували кращих практик послідовного використання all-caps для ключових слів MySQL. Іншими словами, тут нічого не варто зберігати - саме тому я також проголосував за видалення цієї публікації.
mickmackusa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.