2011-12-15 3 views
6

Я пытаюсь удалить неиспользуемые строки из таблицы. Это упрощенный пример моей проблемы:Как удалить неиспользуемые строки из таблицы БД с помощью SQL?

Есть 2 таблицы:

user table: 

user_id user_name 
-------------------- 
1   Mike 
3   Carol 
8   Eric 


address table: 

user_id address 
----------------------- 
1   [email protected]   
3   [email protected] 
10   [email protected] 
3   [email protected] 

Я хочу удалить неиспользуемые адреса из таблицы адресов. Если user_id адреса существует в таблице пользователя, адрес не используется. В таблице примеров есть один неиспользуемый адрес: [email protected]

Я новичок в SQL, и мое решение было некрасиво:

DELETE FROM address 
    WHERE NOT EXISTS 
    (SELECT * FROM user WHERE address.user_id = user.user_id); 

Там должен быть лучший способ сделать это. Каков наилучший способ сделать это?

sqlite используется.

+4

Не выглядит слишком уродливым для меня, что вы хотите улучшить - посмотрите, производительность? –

+0

Вот как бы я это сделал. После того, как вы установили ссылочную целостность, это не повторится. Если у вас нет/не может быть ссылочной целостности, тогда «уродливое» - лучшее, что вы можете иметь. –

+0

@paul: Я просто ищу обычную практику, как эта проблема обычно решается. Кроме того, я беспокоился о производительности: похоже, что поиск инструкции select выполняется один раз для каждой строки таблицы адресов. – SKi

ответ

4

Делают это так:

DELETE FROM address 
    WHERE user_id NOT IN (SELECT user_id FROM user); 
4

В вашем случае, вы должны рассмотреть вопрос о создании user_id в качестве первичного ключа в user и в качестве внешнего ключа в address. Таким образом, если вы удалите одного из своих пользователей в user, вы можете установить опцию ON DELETE CASCADE для автоматического удаления связанных строк по адресу.

В процессе создания вашей таблицы, вам нужно только сделать что-то вроде этого:

CREATE TABLE user (
    user_id INTEGER, 
    user_name VARCHAR(30), 
    PRIMARY KEY (user_id) 
); 

CREATE TABLE address (
    user_id INTEGER, 
    address VARCHAR(30), 
    PRIMARY KEY (user_id, address), 
    FOREIGN KEY (user_id) REFERENCES user(user_id) 
    ON DELETE CASCADE 
); 

В принципе, каждый пользователь имеет уникальный user_id. Если вы удалите одного из этих пользователей, соответствующие адреса в address также будут удалены, поскольку user.user_idaddress.user_id «указывает на» был удален.

Если вы хотите удалить только те неиспользуемые адреса, ваше решение должно работать нормально.

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