Der Unterschied und die Gründe zwischen den MySQL-Abfragebedingungen nicht in und in

Der Unterschied und die Gründe zwischen den MySQL-Abfragebedingungen nicht in und in

Schreiben Sie zuerst ein SQL

Wählen Sie DISTINCT von_id
VON Kabeljau
WO cod.from_id NICHT IN (37, 56, 57)

Als ich heute SQL schrieb, stellte ich fest, dass die Abfrageergebnisse unvollständig waren, NULL-Werte fehlten und sogar NULL-Werte ausgeschlossen wurden, wenn sie nicht vorhanden waren.

Bei Verwendung von in ist kein Nullwert enthalten.

Ich habe das Gefühl, dass MySQL nicht richtig konzipiert ist.

Denn ich dachte immer, dass „in“ und „nicht in“ sich ergänzen sollten, so wie die ganze Suche so aussehen sollte:

Wählen Sie DISTINCT von_id
VON Kabeljau
WO cod.from_id NICHT IN (37, 56, 57) oder cod.from_id IN (37, 56, 57)

Das Ergebnis ist wie erwartet, es fehlt ein Null

Später habe ich online nachgeschaut und eine plausible Erklärung gefunden:

null ist falsch, wenn man es mit einem beliebigen Wert vergleicht

Wenn from_id beispielsweise (37, 56, 57,28,null) ist, ist „not in (37, 56, 57)“ im Vergleich mit 28 wahr, sodass 28 im Ergebnissatz erscheint.

Wenn null mit der Bedingung nicht in (37, 56, 57) verglichen wird, ist das Ergebnis falsch und erscheint daher nicht im Ergebnissatz.

Ergänzung: So behandeln Sie NULL-Werte auf beiden Seiten von MySQL-Bedingungsabfragen IN und NOT IN

Thema

Bei einem Tabellenbaum ist „id“ die Nummer des Baumknotens und „p_id“ die ID des übergeordneten Knotens.

+----+------+

| Ich würde | p_id |

+----+------+

| 1 | NULL |

| 2 | 1 |

| 3 | 1 |

| 4 | 2 |

| 5 | 2 |

+----+------+

Jeder Knoten im Baum gehört zu einem von drei Typen:

Blatt: Wenn dieser Knoten keine untergeordneten Knoten hat.

Wurzel: Wenn dieser Knoten die Wurzel des gesamten Baums ist, d. h., er hat keinen übergeordneten Knoten.

Interner Knoten: Wenn der Knoten weder ein Blattknoten noch ein Wurzelknoten ist.

Schreiben Sie eine Abfrageanweisung, um die Nummern und Typen aller Knoten auszugeben, und sortieren Sie die Ergebnisse nach Knotennummer. Das Ergebnis des obigen Beispiels ist:

+----+------+

| Ich würde | TYP |

+----+------+

| 1 | Wurzel |

| 2 | INNEN|

| 3 | Blatt |

| 4 | Blatt |

| 5 | Blatt |

+----+------+

erklären

Knoten „1“ ist der Stammknoten, da sein übergeordneter Knoten NULL ist und er über die untergeordneten Knoten „2“ und „3“ verfügt.

Knoten „2“ ist ein interner Knoten, da er einen übergeordneten Knoten „1“ und außerdem die untergeordneten Knoten „4“ und „5“ hat.

Die Knoten „3“, „4“ und „5“ sind Blattknoten, da sie einen übergeordneten Knoten, aber keine untergeordneten Knoten haben.

Der Baum in diesem Beispiel sieht folgendermaßen aus:

 1

 / \\

 dreiundzwanzig

 / \\

 4 5

Erstellen Sie zuerst die Tabelle

1. Erstellen Sie eine Tabelle

CREATE TABLE-Baum (
Ich würde INT,
p_id INT 
)

So mache ich es:

SELECT-ID, (
FALL 
 WENN tree.p_id NULL IST, DANN „Root“
 WHEN tree.id NOT IN ( -- Wenn die ID nicht in der Spalte p_id des übergeordneten Knotens steht, wird sie als Blattknoten betrachtet, was logisch korrekt ist!
 Wählen Sie p_id
 Vom Baum
 GROUP BY p_id
 ) DANN 'Blatt'
 SONST 'Inner'
ENDE
)TYP
Vom Baum

Ich denke, wenn die ID nicht in der Spalte p_id des übergeordneten Knotens steht, wird dieser als Blattknoten betrachtet. Es gibt überhaupt kein logisches Problem. Allerdings liegen die Dinge nicht so einfach. Die Abfrageergebnisse lauten wie folgt: Ab id=3 habe ich nicht die gewünschten Ergebnisse gefunden! Ist das nicht unglaublich?

Nach einer weiteren Nacht habe ich das Problem endlich gelöst. Ich werde zunächst den richtigen Ansatz beschreiben:

SELECT-ID, (
FALL 
 WENN tree.p_id NULL IST, DANN „Root“
 WENN tree.id NICHT IN (
 Wählen Sie p_id
 Vom Baum
 WHERE p_id IS NOT NULL -- Eine SQL-Anweisung wurde hinzugefügt
 GROUP BY p_id
 ) DANN 'Blatt'
 SONST 'Inner'
ENDE
)TYP
Vom Baum

Warum passiert das?

es ist bekannt

Der IN-Operator in MySQL wird verwendet, um zu bestimmen, ob der Wert eines Ausdrucks in einer gegebenen Liste enthalten ist. Wenn ja, ist der Rückgabewert 1, andernfalls ist der Rückgabewert 0.

Die Funktion von NOT IN ist genau das Gegenteil von IN. NOT IN wird verwendet, um zu bestimmen, ob der Wert des Ausdrucks in der angegebenen Liste nicht vorhanden ist. Wenn nicht, ist der Rückgabewert 1, andernfalls ist der Rückgabewert 0.

So verwenden wir es normalerweise und das Ergebnis ist das gewünschte. Allerdings stoßen wir häufig auf folgende Sondersituationen!

(1) Auf beiden Seiten von in oder nicht in gibt es keine NULL-Werte

[Beispiel 1] Verwenden der Operatoren IN und NOT IN in SQL-Anweisungen:

mysql> SELECT 2 IN (1,3,5,'danke'),'danke' IN (1,3,5, 'danke');
+---------------------+-------------------------+
| 2 IN (1,3,5,'danke') | 'danke' IN (1,3,5, 'danke') |
+---------------------+-------------------------+
| 0 | 1 |
+---------------------+-------------------------+
1 Zeile im Satz, 2 Warnungen (0,00 Sek.)

mysql> AUSWÄHLEN 2 NICHT IN (1,3,5,'thks'),'thks' NICHT IN (1,3,5, 'thks');
+-------------------------+----------------------------------+
| 2 NICHT IN (1,3,5,'thks') | 'thks' NICHT IN (1,3,5, 'thks') |
+-------------------------+----------------------------------+
| 1 | 0 |
+-------------------------+----------------------------------+
1 Zeile im Satz, 2 Warnungen (0,00 Sek.)

Aus den Ergebnissen können wir erkennen, dass die Rückgabewerte von IN und NOT IN genau entgegengesetzt sind.

Aber ich habe das NULL-Wert-Problem ignoriert

Umgang mit NULL-Werten

Wenn eine der Seiten des IN-Operators NULL ist, ist der Rückgabewert NULL, wenn keine Übereinstimmung gefunden wird. Wenn eine Übereinstimmung gefunden wird, ist der Rückgabewert 1.

(2) NULL-Werte liegen auf beiden Seiten von in

Bitte beachten Sie die folgende SQL-Anweisung:

mysql> SELECT NULL IN (1,3,5,'danke'),10 IN (1,3,NULL,'danke');
+------------------------+-------------------------+
| NULL IN (1,3,5,'danke') | 10 IN (1,3,NULL,'danke') |
+------------------------+-------------------------+
| NULL | NULL |
+------------------------+-------------------------+
1 Zeile im Satz, 1 Warnung (0,00 Sek.)

mysql> SELECT NULL IN (1,3,5,'danke'),10 IN (1,10,NULL,'danke');
+------------------------+---------------+
| NULL IN (1,3,5,'danke') | 10 IN (1,10,NULL,'danke') |
+------------------------+---------------+
| NULL | 1 |
+------------------------+---------------+
1 Zeile im Satz (0,00 Sek.)

(3) NULL auf einer Seite von NOT IN

NOT IN ist genau das Gegenteil. Wenn eine der beiden Seiten des NOT IN-Operators ein Nullwert NULL ist und keine Übereinstimmung gefunden wird, ist der Rückgabewert NULL; wenn eine Übereinstimmung gefunden wird, ist der Rückgabewert 0.

Bitte beachten Sie die folgende SQL-Anweisung:

mysql> AUSWÄHLEN NULL NICHT IN (1,3,5,'thks'),10 NICHT IN (1,0,NULL,'thks');
+----------------------------+-----------------------------------------+
| NULL NICHT IN (1,3,5,'thks') | 10 NICHT IN (1,0,NULL,'thks') |
+----------------------------+-----------------------------------------+
| NULL | NULL |
+----------------------------+-----------------------------------------+
1 Zeile im Satz, 1 Warnung (0,00 Sek.)

mysql> WÄHLEN SIE NULL NICHT IN (1,3,5,'thks'),10 NICHT IN (1,10,NULL,'thks');
+----------------------------+-------------------+
| NULL NICHT IN (1,3,5,'thks') | 10 NICHT IN (1,10,NULL,'thks') |
+----------------------------+-------------------+
| NULL | 0 |
+----------------------------+-------------------+
1 Zeile im Satz (0,00 Sek.)

Basierend auf dem Ergebnis von (3) NULL auf einer Seite von NOT IN können wir das Problem erkennen

Lassen Sie uns zunächst die folgende SQL-Anweisung abfragen und langsam das Problem finden

Wählen Sie p_id
Vom Baum
GROUP BY p_id

Die obigen Abfrageergebnisse enthalten NULL-Werte

Die folgende SQL-Anweisung wird also nichts finden, da NOT IN NULL zurückgibt

Wählen Sie die ID aus. 
Vom Baum
WO id NICHT IN (
 Wählen Sie p_id
 Vom Baum
 GROUP BY p_id
 )

Möchte man also das Ergebnis abfragen, muss man sich zunächst mit dem NULL-Wert auseinandersetzen! OK, der Fehler ist behoben!

Es gibt eine andere Möglichkeit, dieses Problem zu lösen:

SELECT-ID, (
FALL 
 WENN tree.p_id NULL IST, DANN „Root“
 WENN tree.id IN (
 Wählen Sie p_id
 Vom Baum
 GROUP BY p_id
 ) DANN 'Inner'
 SONST 'Blatt'
ENDE
)TYP
Vom Baum

Warum ist es richtig? Überlassen wir es Ihnen, darüber nachzudenken~

Das Obige ist meine persönliche Erfahrung. Ich hoffe, es kann Ihnen als Referenz dienen. Ich hoffe auch, dass Sie 123WORDPRESS.COM unterstützen werden. Sollten dennoch Fehler oder unvollständige Überlegungen vorliegen, freue ich mich über eine Korrektur.

Das könnte Sie auch interessieren:
  • MySQL ruft Daten basierend auf dem JSON-Feldinhalt als Abfragebedingung ab (einschließlich JSON-Arrays).
  • Detaillierte Erläuterung des Problems der Übereinstimmung, selbst wenn in der MySQL-Abfragebedingung am Ende der Zeichenfolge ein Leerzeichen steht
  • Detaillierte Erklärung der allgemeinen Verwendung von MySQL-Abfragebedingungen
  • Wird der Index in der MySQL-Abfragebedingung verwendet?
  • Analyse des Unterschieds zwischen „Platzieren auf“ und „Wo“ in MySQL-Abfragebedingungen
  • MySQL erklärt, wie man Abfragebedingungen optimiert

<<:  Detailliertes Tutorial zur Installation von Docker und der Docker-Compose-Suite unter Windows

>>:  Docker-Compose-Installation DB2-Datenbankbetrieb

Artikel empfehlen

HTML-Tabellen-Tag-Tutorial (7): Hintergrundfarbattribut BGCOLOR

Die Hintergrundfarbe der Tabelle kann über das At...

CSS-Menüschaltflächenanimation

Um ein Dropdown-Menü zu schreiben, klicken Sie au...

So lösen Sie das Problem der Groß-/Kleinschreibung bei MySQL-Abfragen

Frage Als ich kürzlich ein praktisches Projekt mi...

Tutorial zur Installation und Konfiguration von MySQL 5.7.16 ZIP-Paketen

In diesem Artikel finden Sie das Installations- u...

HTTP-Statuscodes

Dieser Statuscode gibt Auskunft über den Status d...

Nginx kompiliert nginx - neues Modul hinzufügen

1. Vorhandene Module anzeigen /usr/local/nginx/sb...

JavaScript, um die Idee des Schlangenspiels umzusetzen

Die Implementierungsidee des Javascript-Spiels Sn...

SQL-Implementierung LeetCode (176. Zweithöchstes Gehalt)

[LeetCode] 176. Zweithöchstes Gehalt Schreiben Si...

So begrenzen Sie die Anzahl der Datensätze in einer Tabelle in MySQL

Inhaltsverzeichnis 1. Lösung auslösen 2. Partitio...

Ein Beispiel für das elegante Schreiben von Urteilen in JavaScript

Inhaltsverzeichnis Vorwort 1. Monadisches Urteil ...