Nicht ganz. Es wäre vielleicht klarer, wenn wir @simons Abfrage leicht umformatieren:
SELECT
cu.*,
ue.email
FROM category_users cu
JOIN user_emails ue ON ue.user_id = cu.user_id
WHERE (category_id = '10' AND ue.primary = true)
Die Bedingungen category_id und ue.primary gehören beide zum WHERE-Klausel und werden mit AND verknüpft. Wenn du eine der Bedingungen entfernst, lässt du das AND weg, behältst aber die WHERE-Klausel bei.
Die meisten einfachen SQL-Abfragen folgen diesem Muster:
SELECT <gewünschte_dinge>
FROM <tabellen>
WHERE <filterbedingungen>
Du kannst die WHERE-Klausel ganz weglassen, aber dann erhältst du jede Zeile aus den angegebenen Tabellen zurück.
Hier ist deine ursprüngliche Abfrage (umformatiert):
SELECT *
FROM category_users
WHERE category_id = '10'
-
“SELECT *” bedeutet, dass die Abfrage alle Spalten aus allen beteiligten Tabellen zurückgeben soll.
-
“FROM category_users” gibt die Tabelle an, die du abfragen möchtest. Die Tabelle category_users enthält Zeilen, die etwa so aussehen:
| id |
category_id |
user_id |
notification_level |
| 1 |
1 |
1 |
3 |
| 2 |
1 |
2 |
3 |
| 3 |
3 |
1 |
3 |
category_id und user_id werden Fremdschlüssel genannt, da sie auf eine Zeile in einer anderen Tabelle verweisen (in diesem Fall die Tabellen categories und users). Die drei Zeilen oben bedeuten also, dass der Benutzer mit der ID 1 die Kategorien 1 und 3 verfolgt und der Benutzer mit der ID 2 die Kategorie 1 verfolgt. Das Feld notification_level gibt an, ob sie Verfolgen, Ersten Beitrag verfolgen oder Beobachten eingestellt haben.
-
“WHERE category_id = '10'” bedeutet, dass du nur an Zeilen interessiert bist, in denen der Wert in der Spalte category_id gleich 10 ist. Ohne diese Zeile würdest du jede Zeile aus der Tabelle category_users erhalten.
@simon hat dir eine neue Version gegeben, die die E-Mail-Adresse des Benutzers hinzufügt:
Diese Abfrage hat aus zwei Gründen einige Änderungen gegenüber deiner ursprünglichen vorgenommen: E-Mail-Adressen werden in einer anderen Tabelle gespeichert (der Tabelle user_emails), und Benutzer können mehr als eine E-Mail-Adresse haben.
-
Im SELECT-Teil:
- “
cu.*” bedeutet „alle Spalten aus der Tabelle cu"
- “
ue.email” bedeutet „die Spalte email aus der Tabelle ue"
-
Im FROM-Teil:
-
Die Tabelle category_users hat jetzt einen Alias, „cu", was die Eingabe spart, wenn du mehrmals darauf Bezug nehmen musst.
-
Wir haben mit JOIN auf die Tabelle user_emails zugegriffen und ihr den Alias ue gegeben.
Die Tabelle user_emails enthält Zeilen wie diese:
Das bedeutet, dass der Benutzer mit der ID 1 zwei E-Mail-Adressen hat: alex@example.com (die primäre Adresse) und alex@other.example.com (eine sekundäre Adresse). Der Benutzer mit der ID 2 hat nur eine Adresse.
Wenn du in SQL zwei Tabellen mit JOIN verbindest, musst du der Datenbank normalerweise mitteilen, was die Verknüpfungsbedingung ist. Wenn du das nicht tust, weiß die Datenbank nicht, welche Werte in den einzelnen Tabellen übereinstimmen sollen, und du erhältst jede mögliche Kombination von Zeilen aus den beiden Tabellen. Wenn du diese Abfrage schreiben würdest:
SELECT *
FROM category_users
JOIN user_emails
…würdest du mit den obigen Beispieldaten 9 Zeilen zurückbekommen: Du würdest die erste Zeile aus category_users dreimal erhalten, jeweils einmal mit jeder Zeile aus user_emails, dann ebenso die zweite Zeile aus category_users dreimal und schließlich die dritte Zeile aus category_users ebenfalls dreimal.
Die Verknüpfungsbedingung teilt der Datenbank normalerweise mit, welche Spalte in den beiden Tabellen denselben Wert repräsentiert. In diesem Fall repräsentieren sowohl die Spalte category_users.user_id als auch die Spalte user_emails.user_id denselben Wert. Indem wir nach JOIN user_emails ue ON ue.user_id = cu.user_id schreiben, weisen wir die Datenbank an, die Zeilen aus user_emails den entsprechenden Zeilen aus category_users zuzuordnen.
-
Selbst mit der Verknüpfungsbedingung erhalten wir für den Benutzer mit der ID 1 immer noch 4 Zeilen zurück, da er 2 Kategorien verfolgt und 2 E-Mail-Adressen hat – wir erhalten eine Zeile für jede Kombination. Daher hat @simon eine zusätzliche Bedingung zur WHERE-Klausel hinzugefügt, damit die Abfrage nur Zeilen mit der primären E-Mail-Adresse des Benutzers zurückgibt. Diese Bedingung kommt zusätzlich zur bereits vorhandenen Bedingung hinzu (Einschränkung der Kategorie-ID) – damit Zeilen zurückgegeben werden, müssen sowohl category_id = '10' als auch ue.primary = true gelten.
Da du deine Suche nicht auf eine einzelne Kategorie einschränken wolltest, musstest du lediglich den Filter category_id entfernen. Du möchtest die gesamte WHERE-Klausel nicht entfernen, da du weiterhin nur primäre E-Mail-Adressen zurückgeben möchtest. Mit anderen Worten hat sich deine Filterbedingung von:
category_id = '10' AND ue.primary = true
zu
ue.primary = true
geändert.
Puh! Ich hoffe, das alles ergibt Sinn 