phpbar.de logo

Mailinglisten-Archive

=?ISO-8859-1?Q?Erkl=E4rung?= eines LEFT JOINS mit Beispiel

Erklärung eines LEFT JOINS mit Beispiel

Patrick Bierans mysql_(at)_lists.phpcenter.de
Fri, 18 May 2001 11:11:00 +0100


LEFT JOIN

Es ist nicht leicht zu verstehen, wie ein JOIN funktioniert. Daher 
erkläre ich das Ganze mal an einem Beispiel:

Ich habe eine Tabelle "user" und eine andere Tabelle "note". Die 
Tabellen sind über das Feld "uid" (userid) logisch miteinander 
verbunden - so etwas wir ein foreign key gibt es in MySQL nicht. Im 
Laufe der Jahre sind Benutzer hinzugekommen, haben Notizen angelegt und 
sind dann irgendwann mal über eine Routine gelöscht worden. Und jetzt 
stellen wir fest, daß die Routine fehlerhaft war, und es noch massig 
Notizen gibt, für die es keinen Benutzerdatensatz mehr gibt.

Jetzt will ich einen Gültigkeitsprüfer bauen, der folgendes macht: 
"Suche alle Notizen, für die es keinen Benutzerdatensatz mehr gibt."

Legen wir die ganze Struktur doch mal an:

create database test;
use test;
create table user
(
  uid integer unsigned not null auto_increment,  # user-id
  unique cart_pkey1 (uid)
);
create table note
(
  nid integer unsigned not null auto_increment,  # note-id
  uid integer unsigned not null,                 # user-id
  content text,
  unique aic_pkey1 (nid)
);
insert into user (uid) values (1111),(2222),(3333),(4444);
insert into note (nid,uid) values 
(1,1111),(2,1111),(3,2222),(4,3333),(6,5555);

select * from user;
select * from note;

Jetzt müßte folgendes da stehen:

+------+
| uid  |
+------+
| 1111 |
| 2222 |
| 3333 |
| 4444 |
+------+

+-----+------+---------+
| nid | uid  | content |
+-----+------+---------+
|   1 | 1111 | NULL    |
|   2 | 1111 | NULL    |
|   3 | 2222 | NULL    |
|   4 | 3333 | NULL    |
|   6 | 5555 | NULL    |
+-----+------+---------+

Also hat die Notiz mit der nid 6 keinen passenden Datensatz in der 
Tabelle "user", da die uid in "note" ja 5555 ist und es keinen 
Datensatz in der Tabelle "user" mit uid 5555 gibt. Das immer von Hand 
zu machen ist nicht gut. Daher wollen wir ein Select bauen, was und da 
hilft. Meine erste Idee war:

select user.uid from user, note where user.uid!=note.uid;

+------+
| uid  |
+------+
| 2222 |
| 3333 |
| 4444 |
| 2222 |
| 3333 |
| 4444 |
| 1111 |
| 3333 |
| 4444 |
| 1111 |
| 2222 |
| 4444 |
| 1111 |
| 2222 |
| 3333 |
| 4444 |
+------+

Ging voll in die Hose. Aber wie dann? Der Trick ist dieser: Mit einem 
LEFT JOIN verbinden wir die Tabellen "user" und "note" über das Feld 
uid. Es wird für jede Notiz mindestends ein Datensatz erzeugt. Die 
Felder des passenden Users werden dann angehängt. Gibt es keinen 
passenden User, so werden die Werte mit NULL gefüllt. Gibt es mehrere 
User einer Notiz (nicht in diesem Beispiel), so würde für jeden 
passenden User ein Datensatz angelegt werden und die Feldwerte der 
Notiz würden wiederholt werden.

"select * from note left join user on note.uid=user.uid;"

+-----+------+---------+------+
| nid | uid  | content | uid  |
+-----+------+---------+------+
|   1 | 1111 | NULL    | 1111 |
|   2 | 1111 | NULL    | 1111 |
|   3 | 2222 | NULL    | 2222 |
|   4 | 3333 | NULL    | 3333 |
|   6 | 5555 | NULL    | NULL |
+-----+------+---------+------+

Das ist schon besser. Und hier ist der Trick: Für die Datensätze aus
"note", für die es keinen Datensatz in der Tabelle "user" gibt ist
die uid in der Tabelle "user" NULL.

"select * from note left join user on note.uid=user.uid where user.uid 
is null;"


+-----+------+---------+------+
| nid | uid  | content | uid  |
+-----+------+---------+------+
|   6 | 5555 | NULL    | NULL |
+-----+------+---------+------+

Geht doch.

Jetzt räumen wir noch schnell auf, damit alles wie vorher ist.

drop database test;

Stay cool, don't close the fridge.

Autor: pbierans_(at)_lynet.de


P. Bierans

--
LYNET Kommunikation AG - http://www.lynet.de - Patrick Bierans
Das Internet-Systemhaus fuer Multimedia- und Netzwerkloesungen
Zentrale Luebeck      Fon +49-451-6131-0, Fax +49-451-6131-333
Niederlassung Hamburg Fon +49-40-65738-0, Fax +49-40-65738-333

---
*** Weitere Infos zur Mailingliste und MySQL unter http://www.4t2.com/mysql 



php::bar PHP Wiki   -   Listenarchive