2017-09-26 1 views
0

Ich habe ein paar Tische wie folgt definiert:besserer Ansatz für mehr negierte Subqueries

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`) 
) 

Die members_to_delete Tabelle eine Untergruppe von Mitgliedern enthält.

Ich möchte alle Zeilen in der Nachrichtentabelle nur auswählen (und möglicherweise löschen), wenn weder sender_id noch recipient_id in der Tabelle members_to_delete vorhanden sind. So kam ich mit dieser hässlichen Abfrage nach oben:

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); 

ich dort Figur ein viel besserer Weg sein muss, um diese Abfrage zu schreiben, aber ich bin nicht sicher, was es ist. Was wäre eine effizientere Möglichkeit, diese Art von Abfrage zu schreiben?

Antwort

2

Sie können die Technik in Return row only if value doesn't exist für mehrere Spalten verwenden.

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

Ich konzentrierte mich hauptsächlich darauf, ob 'IN()' die richtige Bedingung dafür ist, oder ich muss mehrere Joins machen. – Barmar

+0

Dort ging ich anfangs, aber dann sah ich deine und wollte nicht darüber nachdenken, welche Indizes existieren könnten. – xQbert

+0

Super, danke @Barmar! –

Verwandte Themen