2017-09-26 18 views
0

我有這樣定義了幾桌:多好的辦法否定子查詢

CREATE TABLE `member` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    ... 
) 

CREATE TABLE `members_to_delete` (
    `id` bigint(20), 
    ... 
) 

CREATE TABLE `message` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `sender_id` bigint(20) NOT NULL, 
    `recipient_id` bigint(20) DEFAULT NULL, 
    ... 
    CONSTRAINT `_FK1` FOREIGN KEY (`sender_id`) REFERENCES `member` (`id`), 
    CONSTRAINT `_FK2` FOREIGN KEY (`recipient_id`) REFERENCES `member` (`id`) 
) 

的members_to_delete表包含成員的子集。

只有在members_to_delete表中既不存在sender_id也不存在recipient_id時,纔想選擇(並最終刪除)消息表中的所有行。所以,我想出了這個醜陋的查詢:

SELECT id FROM message WHERE sender_id NOT IN (SELECT id FROM members_to_delete) 
AND recipient_id NOT IN (SELECT id FROM members_to_delete); 

我想一定有寫這個查詢一種更好的方式,但我不知道它是什麼。什麼是寫這種查詢的更有效的方法?

回答

2

對於多列,您可以使用Return row only if value doesn't exist中的技術。

SELECT m.id 
FROM message AS m 
LEFT JOIN members_to_delete AS d 
ON d.id IN (m.sender_id, m.recipient_id) 
WHERE d.id IS NULL 
+0

我主要關注的是IN()是否是正確的條件,或者我需要做多個連接。 – Barmar

+0

這就是我最初的目標,但後來我看到了你的想法,並且不想考慮可能存在的索引。 – xQbert

+0

太棒了,謝謝@Barmar! –