phpbar.de logo

Mailinglisten-Archive

Select und Maximalwert

Select und Maximalwert

Patrick Bierans mysql_(at)_lists.phpcenter.de
Tue, 15 May 2001 09:21:29 +0100


> Außerdem ist in mysql die Konstruktion "select * from tabelle where kenn
> in (select id from andere_tabelle where ...." nicht möglich. Du kannst
> also nur das Ergebnis der Gruppierung in eine eigene (temporäre) Tabelle
> (z. B. "tempKunde") schreiben [...]

Anm.: Es gehen auch Joins als Ersatz für Subselects.

http://www.mysql.com/doc/M/i/Missing_Sub-selects.html
http://www.mysql.com/doc/J/O/JOIN.html

In dem Threat "Re: Wollt Ihr eine FAQ und mehr?" habe ich einen LEFT
join beschrieben; daß paßt nicht 100%ig auf dieses Problem, sollte
aber die Angst vor Joins nehmen:

--- som:
From:           	Patrick Bierans <pbierans_(at)_lynet.de>
To:             	mysql-de_(at)_lists.4t2.com
Subject:        	Re: Wollt Ihr eine FAQ und mehr?
Date sent:      	Tue, 8 May 2001 12:08:28 +0100

> Hallo Patrick,
> na dann schreibe doch einfach etwas über Join.

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 "cart" als Warenkorb und eine andere Tabelle 
"art_in_cart", die mir die Artikel und Mengen des Warenkorbes aufzeigt. 

Die Tabelle sind über das Feld "cid" logisch miteinander verbunden 
(soetwas wir ein foreign key gibt es in MySQL nicht). Jetzt will ich 
einen Gültigkeitsprüfer bauen, der folgendes macht:

"Suche alle Datensätze aus der Tabelle "art_in_cart", für die es keinen 

Datensatz in der Tabelle "cart" gibt."

Legen wir die ganze Struktur doch mal an:

create database test;
user test;
create table cart
(
  cid integer unsigned not null auto_increment,  # cart-id
  uid integer unsigned not null,                 # user-id
  status varchar(16) default "neu",
  unique cart_pkey1 (cid)
);
create table art_in_cart
(
  aicid integer unsigned not null auto_increment,# art_in_cart-id
  cid integer unsigned not null,                 # cart-id
  aid integer unsigned not null,                 # article-id
  qty integer unsigned not null default 1,
  unique aic_pkey1 (aicid)
);

Und hier ein paar Demodaten:

insert into cart (uid) values (1),(2),(3),(4);
insert into art_in_cart (cid,aid) values 
(1,2),(1,3),(1,4),(4,9),(6,12);

"select * from cart;" liefert jetzt:

+-----+-----+--------+
| cid | uid | status |
+-----+-----+--------+
|   1 |   1 | neu    |
|   2 |   2 | neu    |
|   3 |   3 | neu    |
|   4 |   4 | neu    |
+-----+-----+--------+

"select * from art_in_cart;" liefert jetzt:

+-------+-----+-----+-----+
| aicid | cid | aid | qty |
+-------+-----+-----+-----+
|     1 |   1 |   2 |   1 |
|     2 |   1 |   3 |   1 |
|     3 |   1 |   4 |   1 |
|     4 |   4 |   9 |   1 |
|     5 |   6 |  12 |   1 |
+-------+-----+-----+-----+

Also hat der Datensatz in der Tabelle "art_in_cart" mit der aicid 5 
keinen passenden Datensatz in der Tabelle "cart", da die cid in 
"art_in_cart" ja 6 ist und es keinen Datensatz in der Tabelle "cart" 
mit der cid 6 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 cart.cid from cart, art_in_cart where 
cart.cid!=art_in_cart.cid;"

Hier das Ergebnis:
+-----+
| cid |
+-----+
|   2 |
|   3 |
|   4 |
|   2 |
|   3 |
|   4 |
|   2 |
|   3 |
|   4 |
|   1 |
|   2 |
|   3 |
|   1 |
|   2 |
|   3 |
|   4 |
+-----+

Ging voll in die Hose. Aber wie dann? Der Trick ist dieser: Mit einem 
LEFT JOIN verbinden wir die Tabellen "cart" und "art_in_cart" über das 
Feld cid. Wir kriegen dann sowas wie ein "Kreuzprodukt" (Eine 
Kombination aller Möglichkeiten).

"select * from art_in_cart left join cart on cart.cid=art_in_cart.cid;"

Hier das Ergebnis:

+-------+-----+-----+-----+------+------+--------+
| aicid | cid | aid | qty | cid  | uid  | status |
+-------+-----+-----+-----+------+------+--------+
|     2 |   1 |   0 |   1 |    1 |    1 | neu    |
|     3 |   1 |   0 |   1 |    1 |    1 | neu    |
|     4 |   1 |   0 |   1 |    1 |    1 | neu    |
|     9 |   4 |   0 |   1 |    4 |    4 | neu    |
|    12 |   6 |   0 |   1 | NULL | NULL | NULL   |
+-------+-----+-----+-----+------+------+--------+

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

die cid in der Tabelle "cart" NULL.

"select * from art_in_cart left join cart on cart.cid=art_in_cart.cid 
where cart.cid is null;"

Hier das Ergebnis:
+-------+-----+-----+-----+------+------+--------+
| aicid | cid | aid | qty | cid  | uid  | status |
+-------+-----+-----+-----+------+------+--------+
|    12 |   6 |   0 |   1 | NULL | 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

--- eom

Ein normaler Join ist natürlich einfacher.


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