phpbar.de logo

Mailinglisten-Archive

Re: A aber nicht B - Ich HABS endlich!
Archiv Mailingliste mysql-de

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A aber nicht B - Ich HABS endlich!




>Also alle, die in A enthalten sind, in B überhaupt keine Entsprechung haben
>(a_id=4) und alle diejenigen, die in A enthalten sind, in B aber keine
>Entsprechung für B.bedingung=200 (a_id=1, a_id=3) haben.

So gehts:

mysql> SELECT DISTINCT A.a_id
    -> FROM A
    -> LEFT JOIN B ON A.a_id=B.a_id
    -> LEFT JOIN B AS C ON B.a_id=C.a_id AND C.bedingung='200'
    -> WHERE B.bedingung IS NULL OR C.bedingung IS NULL;
+------+
| a_id |
+------+
|    1 |
|    3 |
|    4 |
+------+
3 rows in set (0.00 sec)

Das ist komplizierter als man anfangs denkt (zumindest als ich dachte). Man
braucht --
im Nachhinein ist mir klar warum -- einen zweiten LEFT JOIN, weil man
jeweils innerhalb
jeden Satzes B.a_id prüfen muss, ob EINER bedingung=200 hat:

B.a_id=C.a_id AND C.bedingung='200' :: "Füge die zusammen, die die selbe
a_id haben und
bedingung=200" --> das geht nicht bei denen, die wir haben wollen, dort
kriegt man NULL:

--snip--
mysql> SELECT *
    -> FROM B
    -> LEFT JOIN B AS C ON B.a_id=C.a_id AND C.bedingung='200';
+------+------+-----------+------+------+-----------+
| b_id | a_id | bedingung | b_id | a_id | bedingung |
+------+------+-----------+------+------+-----------+
|    1 |    1 | 100       | NULL | NULL | NULL      |
|    2 |    1 | 300       | NULL | NULL | NULL      |
|    3 |    2 | 100       |    4 |    2 | 200       |
|    4 |    2 | 200       |    4 |    2 | 200       |
|    5 |    2 | 300       |    4 |    2 | 200       |
|    6 |    3 | 100       | NULL | NULL | NULL      |
|    7 |    3 | 300       | NULL | NULL | NULL      |
+------+------+-----------+------+------+-----------+
7 rows in set (0.00 sec)
--snip--

Jetzt muss man diesen ganzen Satz mit einem LEFT JOIN über a_id mit A
zusammenfügen.
Das gibt dann:

mysql> SELECT *
    -> FROM A
    -> LEFT JOIN B ON A.a_id=B.a_id
    -> LEFT JOIN B AS C ON B.a_id=C.a_id AND C.bedingung='200';
+------+------+------+------+-----------+------+------+-----------+
| a_id | name | b_id | a_id | bedingung | b_id | a_id | bedingung |
+------+------+------+------+-----------+------+------+-----------+
|    1 | VA 1 |    1 |    1 | 100       | NULL | NULL | NULL      |
|    1 | VA 1 |    2 |    1 | 300       | NULL | NULL | NULL      |
|    2 | VA 2 |    3 |    2 | 100       |    4 |    2 | 200       |
|    2 | VA 2 |    4 |    2 | 200       |    4 |    2 | 200       |
|    2 | VA 2 |    5 |    2 | 300       |    4 |    2 | 200       |
|    3 | VA 3 |    6 |    3 | 100       | NULL | NULL | NULL      |
|    3 | VA 3 |    7 |    3 | 300       | NULL | NULL | NULL      |
|    4 | VA 4 | NULL | NULL | NULL      | NULL | NULL | NULL      |
+------+------+------+------+-----------+------+------+-----------+
8 rows in set (0.00 sec)

Die gesuchten DS sind jetzt die, die ENTWEDER im B- oder im C-Teil Nullen
haben,
weil sie einer Prüfung nicht standgehalten haben. Die kann ich jetzt mit

 "WHERE B.bedingung IS NULL OR C.bedingung"

raussuchen. Wenn man die einzelnen a_id sucht nimmt man noch DISTINCT dazu.
Und ZACK!

Die Lösung ist also:

SELECT DISTINCT A.a_id
FROM A
LEFT JOIN B ON A.a_id=B.a_id
LEFT JOIN B AS C ON B.a_id=C.a_id AND C.bedingung='200'
WHERE B.bedingung IS NULL OR C.bedingung IS NULL;

Gruss, schönen Sonntag abend noch,

    -Florian
--
Caspar Florian Ebeling <cfe_(at)_plannersdelight.net> /
http://www.plannersdelight.net/
Boeblinger Str 63, 70199 Stuttgart, Tel +49 (0) 711 60 70 142

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


Home | Main Index | Thread Index

php::bar PHP Wiki   -   Listenarchive