Probleme mit Join

Probleme mit Join

am 12.07.2007 23:09:50 von Holger Pollmann

Hallo,

ich vermute, daß das Problem,d as ich jetzt shcildere, was mit meinem
mangelhaften Verständnis von Joins zu tun hat...

Also:

Gegeben seien drei Tabellen T1, T2 und T3.

Die Tabellen T1 bis T3 sehen aus wie folgt:

+----+-------+ +----+-----+------+ +----+-----+-------+
| id | titel | | id | ref | name | | id | ref | alter |
+----+-------+ +----+-----+------+ +----+-----+-------+
| 1 | a | | 1 | 1 | x | | 1 | 1 | 13 |
| 2 | b | | 2 | 1 | y | | 2 | 1 | 45 |
| 3 | c | | 3 | 2 | z | | 3 | 1 | 34 |
+----+-------+ +----+-----+------+ +----+-----+-------+

ref in T2 und T3 soll sich jeweils auf die id in T1 beziehen.

Was ich nun will: ein Statement, das mir für jede Zeile in T1 einmal den
ID und den Titel aus T1 liefert, dann aber noch die Anzahl der Zeilen
mit entsprechendem ref aus T2 und T3. Das Ergebnis soll etwa so
aussehen:

+----+-------+--------+--------+
| id | titel | num_t2 | num_t3 |
+----+-------+--------+--------+
| 1 | a | 2 | 3 |
| 2 | b | 1 | 0 |
| 3 | c | 0 | 0 |
+----+-------+--------+--------+

Mein Ansatz:

SELECT
T1.id,
T1.titel,
COUNT(DISTINCT T2.id) AS num_t2,
COUNT(DISTINCT T3.id) AS num_t3
FROM T1
LEFT JOIN
(T2, AS T3)
ON (
T1.id = T2.ref AND
T1.id = T3.ref
)
GROUP BY T1.id

Leider liefert mir das aber:

+----+-------+--------+--------+
| id | titel | num_t2 | num_t3 |
+----+-------+--------+--------+
| 1 | a | 2 | 3 |
| 2 | b | 0 | 0 |
| 3 | c | 0 | 0 |
+----+-------+--------+--------+

Sobald ich in T3 eine solche Zeile einfüge:

+----+-----+-------+
| id | ref | alter |
+----+-----+-------+
| 4 | 2 | 34 |
+----+-----+-------+

wird richtig gezählt:

+----+-------+--------+--------+
| id | titel | num_t2 | num_t3 |
+----+-------+--------+--------+
| 1 | a | 2 | 3 |
| 2 | b | 1 | 1 |
| 3 | c | 0 | 0 |
+----+-------+--------+--------+

Was ist an meinem Join falsch?

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Das saarl. VwVfG läßt eine Interpretation deutscher Gesetze nur dann
zu, wenn sie nicht eindeutig sind." Manfred Saar, Präsident
Apothekerkammer d. Saarlandes. heute-journal v. 8. August 2006.

Re: Probleme mit Join

am 13.07.2007 08:11:56 von Claus Reibenstein

Holger Pollmann schrieb:

> SELECT
> T1.id,
> T1.titel,
> COUNT(DISTINCT T2.id) AS num_t2,
> COUNT(DISTINCT T3.id) AS num_t3
> FROM T1
> LEFT JOIN
> (T2, AS T3)
^^

Hier solltest Du eigentlich einen Syntaxfehler gemeldet bekommen.

Gruß. Claus

Re: Probleme mit Join

am 13.07.2007 08:41:24 von Werner Bauer

Holger Pollmann schrieb:
> ich vermute, daß das Problem,d as ich jetzt shcildere, was mit meinem=
=20
> mangelhaften Verständnis von Joins zu tun hat...

du willst zwei Group counts in eine Statement, das geht so nicht mit Join=
s.

entweder du ermittelst die Zeilenanzahlen in eine temp. Tabelle, oder,=20
wenn du eine genügend neue Mysql-version hast, sozusagen "on-the-fly"

select T1.*,
(select count(*) from t2 where t2.ref=3Dt1.id) as anz-t2,
(select count(*) from t3 where t3.ref=3Dt1.id) as anz-t3
from t1
where ...

HTH, und ausprobiert hab' ich's nicht, und ob das halbwegs optimiert=20
wird, weis ich auch nicht ;-)

Werner

Re: Probleme mit Join

am 13.07.2007 11:47:14 von Holger Pollmann

Claus Reibenstein <4spammersonly@web.de> schrieb:

>> (T2, AS T3)
> ^^
>
> Hier solltest Du eigentlich einen Syntaxfehler gemeldet bekommen.

Jo... denk dir das "AS" einfach weg bitte.

Intern heißen meine Tabellen natürlich anders, ich habe quasi die
eigentlichen Namen gelöscht.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl. Der
Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003

Re: Probleme mit Join

am 13.07.2007 12:46:54 von Holger Pollmann

werner bauer schrieb:

>> ich vermute, daß das Problem,d as ich jetzt shcildere, was mit
>> meinem
>
>> mangelhaften Verständnis von Joins zu tun hat...
>
> du willst zwei Group counts in eine Statement, das geht so nicht mit
> Joins.

Hmmm... weil der Join schon nur bestimmte Zeilen zurückliefert, vermute
ich?

> entweder du ermittelst die Zeilenanzahlen in eine temp. Tabelle,
> oder, wenn du eine genügend neue Mysql-version hast, sozusagen
> "on-the-fly"

MySQL 5.0.30 - Subquerys gehen also

> select T1.*,
> (select count(*) from t2 where t2.ref=t1.id) as anz-t2,
> (select count(*) from t3 where t3.ref=t1.id) as anz-t3
> from t1
> where ...

Das hilft mir nicht (und funktioniert auch nicht); ich brauche ja für
jede Zeile aus T1 einen solchen Count.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl.
Der Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003

Re: Probleme mit Join

am 13.07.2007 14:52:51 von Andreas Sakowski

"Holger Pollmann" schrieb
> Hallo,
>
> ich vermute, daß das Problem,d as ich jetzt shcildere, was mit
> meinem
> mangelhaften Verständnis von Joins zu tun hat...
>
> Also:
>
> Gegeben seien drei Tabellen T1, T2 und T3.
>
> Die Tabellen T1 bis T3 sehen aus wie folgt:
>
> +----+-------+ +----+-----+------+ +----+-----+-------+
> | id | titel | | id | ref | name | | id | ref | alter |
> +----+-------+ +----+-----+------+ +----+-----+-------+
> | 1 | a | | 1 | 1 | x | | 1 | 1 | 13 |
> | 2 | b | | 2 | 1 | y | | 2 | 1 | 45 |
> | 3 | c | | 3 | 2 | z | | 3 | 1 | 34 |
> +----+-------+ +----+-----+------+ +----+-----+-------+
>
> ref in T2 und T3 soll sich jeweils auf die id in T1 beziehen.
>
> Was ich nun will: ein Statement, das mir für jede Zeile in T1 einmal
> den
> ID und den Titel aus T1 liefert, dann aber noch die Anzahl der
> Zeilen
> mit entsprechendem ref aus T2 und T3. Das Ergebnis soll etwa so
> aussehen:
>
> +----+-------+--------+--------+
> | id | titel | num_t2 | num_t3 |
> +----+-------+--------+--------+
> | 1 | a | 2 | 3 |
> | 2 | b | 1 | 0 |
> | 3 | c | 0 | 0 |
> +----+-------+--------+--------+
>
> Mein Ansatz:
>
> SELECT
> T1.id,
> T1.titel,
> COUNT(DISTINCT T2.id) AS num_t2,
> COUNT(DISTINCT T3.id) AS num_t3
> FROM T1
> LEFT JOIN
> (T2, AS T3)
> ON (
> T1.id = T2.ref AND
> T1.id = T3.ref
> )
> GROUP BY T1.id

Die Tabellen T2 und T3 werden als Inner Join
behandelt. Das scheint nicht das zu sein, was Du
willst. Hierbei kommen Zeilen aus t2 und t3 nur
dann dazu, wenn für es in t2 und in t3 passende
Zeilen gibt. Du suchts aber Zeilen, die in t2 oder
in t3 passen.

> Leider liefert mir das aber:
>
> +----+-------+--------+--------+
> | id | titel | num_t2 | num_t3 |
> +----+-------+--------+--------+
> | 1 | a | 2 | 3 |
> | 2 | b | 0 | 0 |
> | 3 | c | 0 | 0 |
> +----+-------+--------+--------+

Was dem entspricht, was Du angefordert hast.

> Sobald ich in T3 eine solche Zeile einfüge:
>
> +----+-----+-------+
> | id | ref | alter |
> +----+-----+-------+
> | 4 | 2 | 34 |
> +----+-----+-------+
>
> wird richtig gezählt:

Es wurde auch vorher richtig gezäht. Nur das Du was anderes
gezählt haben wolltest. Und das nun "richtig" gezählt wird liegt
daran, das bei beidem das selbe Ergebnis rauskommt.

> +----+-------+--------+--------+
> | id | titel | num_t2 | num_t3 |
> +----+-------+--------+--------+
> | 1 | a | 2 | 3 |
> | 2 | b | 1 | 1 |
> | 3 | c | 0 | 0 |
> +----+-------+--------+--------+
>
> Was ist an meinem Join falsch?

Schreibe für t2 und t3 jeweis ein eigenen left join mit
passender join condition und es sollte funktionieren.

Gruß
Andreas

Re: Probleme mit Join

am 13.07.2007 15:28:30 von Holger Pollmann

"Andreas Sakowski" schrieb:

> Die Tabellen T2 und T3 werden als Inner Join
> behandelt. Das scheint nicht das zu sein, was Du
> willst. Hierbei kommen Zeilen aus t2 und t3 nur
> dann dazu, wenn für es in t2 und in t3 passende
> Zeilen gibt. Du suchts aber Zeilen, die in t2 oder
> in t3 passen.

Ahh... okay, ich glaube, ich verstehe.

>> Was ist an meinem Join falsch?
>
> Schreibe für t2 und t3 jeweis ein eigenen left join mit
> passender join condition und es sollte funktionieren.

Gut.

Nur: wie? Irgendwie dachte ich, man könnte mehrere LEFT JOINs so angeben,
wie ich das gemacht habe, aber das ises ja nicht...

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl.
Der Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003

Re: Probleme mit Join

am 13.07.2007 15:42:38 von Andreas Sakowski

"Holger Pollmann" schrieb im Newsbeitrag
> "Andreas Sakowski" schrieb:
>> Schreibe für t2 und t3 jeweis ein eigenen left join mit
>> passender join condition und es sollte funktionieren.
>
> Gut.
>
> Nur: wie? Irgendwie dachte ich, man könnte mehrere LEFT JOINs so
> angeben,
> wie ich das gemacht habe, aber das ises ja nicht...

http://dev.mysql.com/doc/refman/5.0/en/join.html

schreib left join einfach öfters hin:

from t1
left join t2 on t2.ref = t1.id
left join t3 on t3.ref = t1.id

Schönes Wochenende
Andreas

Re: Probleme mit Join

am 13.07.2007 18:05:27 von Werner Bauer

Holger Pollmann schrieb:

>
>> select T1.*,
>> (select count(*) from t2 where t2.ref=t1.id) as anz-t2,
>> (select count(*) from t3 where t3.ref=t1.id) as anz-t3
>> from t1
>> where ...
>
> Das hilft mir nicht (und funktioniert auch nicht);

doch, es waren nur so Schlampigkeitsfehler wie ant-t2 was ja wohl kein
Feldname sein darf ...

CREATE TABLE `t1` (
`id` INT NOT NULL ,
`titel` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `t1` ( `id` , `titel` )
VALUES
('1', 'a'),
('2', 'b'),
('3', 'c');

CREATE TABLE `t2` (
`id` INT NOT NULL ,
`ref` INT NOT NULL ,
`name` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `t2` ( `id` , ref, `name` )
VALUES
('1', 1, 'x'),
('2', 1, 'y'),
('3', 2, 'z');

CREATE TABLE `t3` (
`id` INT NOT NULL ,
`ref` INT NOT NULL ,
`alter` VARCHAR( 255 ) NOT NULL
) ENGINE = MYISAM ;

INSERT INTO `t3` ( `id` , ref, `alter` )
VALUES
('1', 1, '13'),
('2', 1, '45'),
('3', 2, '34');


-- und geht doch!


SELECT t1 . * , (

SELECT count( * )
FROM t2
WHERE t2.ref = t1.id
) AS anzt2, (

SELECT count( * )
FROM t3
WHERE t3.ref = t1.id
) AS anzt3
FROM t1

Re: Probleme mit Join

am 13.07.2007 20:42:59 von Claus Reibenstein

werner bauer schrieb:

> Holger Pollmann schrieb:
>
>>> (select count(*) from t2 where t2.ref=t1.id) as anz-t2,
>>
>> Das hilft mir nicht (und funktioniert auch nicht);
>
> doch, es waren nur so Schlampigkeitsfehler wie ant-t2 was ja wohl kein
> Feldname sein darf ...

Doch, darf. Allerdings muss man ihn dann in Backticks setzen. `anz-t2`
sollte also funktionieren.

Schön ist das aber nicht.

Gruß. Claus

Re: Probleme mit Join

am 19.07.2007 16:32:39 von Holger Pollmann

"Andreas Sakowski" schrieb:

>> Nur: wie? Irgendwie dachte ich, man könnte mehrere LEFT JOINs so
>> angeben, wie ich das gemacht habe, aber das ises ja nicht...
>
> http://dev.mysql.com/doc/refman/5.0/en/join.html
>
> schreib left join einfach öfters hin:
>
> from t1
> left join t2 on t2.ref = t1.id
> left join t3 on t3.ref = t1.id

Manchmal... ist man einfach zu doof für die einfachsten Sachen.

Danke, läuft perfekt jetzt.

--
( ROT-13 if you want to email me directly: uvuc@ervzjrexre.qr )
"Sie tragen Trauer? Der Untergang der DDR?" - "Nein, Leni Riefenstahl.
Der Führer hat sie zu sich genommen." -- Abschiedsshow Scheibenwischer,
02.10.2003