Видаліть рядки 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.