MySQL - Left JOIN - Verbunde datensetze suchen (problem: doppel)
MrSpoocy
- datenbank
0 Vinzenz Mai0 MrSpoocy
0 Frank (no reg)0 MrSpoocy
Hi, also ich habe eine Datenbank, die wie folgt aussieht:
CREATE TABLE IF NOT EXISTS `0815` (
`id` int(11) NOT NULL,
`zID` int(10) unsigned NOT NULL,
`Name` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Daten:
INSERT INTO `0815` (`id`, `zID`, `Name`) VALUES
(1, 123, 'Test'),
(2, 123, 'Blub'),
(3, 123, 'Keine Ahnung'),
(4, 436, 'UserBlub'),
(5, 436, 'Random Scheiß'),
(6, 436, 'YX Scheiß ZP'),
(7, 436, 'Weis ich nicht');
Nun möchte ich eine Suche machen welche nach einem Namen sucht und alle einträge die die gleiche zID haben mit auflistet. Habs auch so mehr oder weniger hin bekommen:
SELECT T1.zID,T2.Name FROM `0815` AS T1
LEFT JOIN `0815` AS T2 ON T2.zID = T1.zID
WHERE T1.Name LIKE '%Blub%'
An sich geht es, an sich stimmt die auflistung nun:
zID Name
123 Test
123 Blub
123 Keine Ahnung
436 UserBlub
436 Random Scheiß
436 YX Scheiß ZP
436 Weis ich nicht
Wenn ich ab nun nach "scheiß" suchen lassen dann (was auch logisch ist) listet er die zID 2 mal mit allen dazugehöriegen einträgen auf. Jemand eine
Idee das design oder die abfrage zu verbessern ?
Hallo,
SELECT T1.zID,T2.Name FROM 0815
AS T1
LEFT JOIN
0815
AS T2 ON T2.zID = T1.zID
WHERE T1.Name LIKE '%Blub%'
warum verwendest Du einen [LEFT JOIN](http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#leftright_join)?
Warum verwendest Du keinen [INNER JOIN](http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#inner_join)?
> zID Name
> 123 Test
> 123 Blub
> 123 Keine Ahnung
> 436 UserBlub
> 436 Random Scheiß
> 436 YX Scheiß ZP
> 436 Weis ich nicht
> Wenn ich ab nun nach "scheiß" suchen lassen dann (was auch logisch ist) listet er die zID 2 mal mit allen dazugehöriegen einträgen auf. Jemand eine
> Idee das design oder die abfrage zu verbessern ?
Ein paar Ideen:
- nutze DISTINCT
- gruppiere
- nutze Subselects statt des [Selfjoins](http://aktuell.de.selfhtml.org/artikel/datenbanken/fortgeschrittene-joins/selfjoin.htm).
Prüfe mit [EXPLAIN](http://dev.mysql.com/doc/refman/5.1/de/explain.html) den Aufwand der jeweiligen Lösung.
Freundliche Grüße
Vinzenz
Hallo,
SELECT T1.zID,T2.Name FROM 0815
AS T1
LEFT JOIN
0815
AS T2 ON T2.zID = T1.zID
WHERE T1.Name LIKE '%Blub%'
>
> warum verwendest Du einen [LEFT JOIN](http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#leftright_join)?
> Warum verwendest Du keinen [INNER JOIN](http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#inner_join)?
>
> > zID Name
> > 123 Test
> > 123 Blub
> > 123 Keine Ahnung
> > 436 UserBlub
> > 436 Random Scheiß
> > 436 YX Scheiß ZP
> > 436 Weis ich nicht
>
> > Wenn ich ab nun nach "scheiß" suchen lassen dann (was auch logisch ist) listet er die zID 2 mal mit allen dazugehöriegen einträgen auf. Jemand eine
> > Idee das design oder die abfrage zu verbessern ?
>
> Ein paar Ideen:
>
> - nutze DISTINCT
> - gruppiere
> - nutze Subselects statt des [Selfjoins](http://aktuell.de.selfhtml.org/artikel/datenbanken/fortgeschrittene-joins/selfjoin.htm).
>
> Prüfe mit [EXPLAIN](http://dev.mysql.com/doc/refman/5.1/de/explain.html) den Aufwand der jeweiligen Lösung.
>
>
> Freundliche Grüße
>
> Vinzenz
Hab jetzt mal so versucht:
`SELECT T2.* FROM `0815` AS T1,`0815` AS T2 WHERE T1.zID = T2.zID AND T1.Name LIKE '%Scheiß%' GROUP BY T2.id;`{:.language-sql}
Beim EXPLAIN ist der unterschied das hier "Using temporary; Using filesort" benutzt wird beim JOIN nicht. Bin mir jetzt nicht wirklich sicher was denn nun
von beidem besser ist :/
Hallo,
Ein paar Ideen:
- nutze DISTINCT
- gruppiere
- nutze Subselects statt des Selfjoins.
Hab jetzt mal so versucht:
SELECT T2.* FROM
0815AS T1,
0815AS T2 WHERE T1.zID = T2.zID AND T1.Name LIKE '%Scheiß%' GROUP BY T2.id;
das ist immer noch ein Selfjoin, nur mit impliziter Joinsyntax, die anscheinend ...
Beim EXPLAIN ist der unterschied das hier "Using temporary; Using filesort" benutzt wird beim JOIN nicht. Bin mir jetzt nicht wirklich sicher was denn nun
von beidem besser ist :/
... zu überraschend deutlich schlechterer Performance führt.
using temporary und using filesort findest Du auf der verlinkten Seite zu EXPLAIN weiter unten. Nutze die Suchfunktion, um die Abschnitte zu finden.
Freundliche Grüße
Vinzenz
Hallo,
zID Name
123 Test
123 Blub
123 Keine Ahnung
436 UserBlub
436 Random Scheiß
436 YX Scheiß ZP
436 Weis ich nichtWenn ich ab nun nach "scheiß" suchen lassen dann (was auch logisch ist) listet er die zID 2 mal mit allen dazugehöriegen einträgen auf. Jemand eine
Idee das design oder die abfrage zu verbessern ?
Du hast ja auch 2 Datensätze, die "scheiß" beinhalten. Diese haben zufällig beide dieselbe zID. Ich hab keine Ahnung welcher Zweck sich hinter dieser zID verbirgt, das weisst nur du.
Wenn du jetzt nur eimal jede eindeutige (Stichwort: Distinct) zID anzeigen lassen willst, kannst du das tun. Allerdings ohne Name und mittels DISTINCT oder einem GROUP BY zID. Wenn du den Spalte "Name" mit anzeigen willst, welche Inhalt soll es dir denn dann anzeigen, den vom ersten gefundenen, also "Random Scheiß" oder den vom zweiten gefundenen Datensatz "YX Scheiß ZP"? Kurz gesagt, das geht nicht "einfach so" ...
Mit einer korrelierenden Unterabfrage könntest du dir z.b. den Namen
Was sollte dir ausgegeben werden und warum. Wenn du das "warum" weisst, kannst du es ggf auch in SQL umsetzen mit Aggregatsfunktionen wie MAX() oder MIN() oder sonstigen Möglichkeiten deines Datenbanksystems.
Die Möglichkeit mit GROUP BY, die mySql dir bietet ist fachlich falsch.
Ciao, Frank
Was sollte dir ausgegeben werden und warum. Wenn du das "warum" weisst, kannst du es ggf auch in SQL umsetzen mit Aggregatsfunktionen wie MAX() oder MIN() oder sonstigen Möglichkeiten deines Datenbanksystems.
Die Möglichkeit mit GROUP BY, die mySql dir bietet ist fachlich falsch.
Ciao, Frank
die zID ist eine art zugehörigkeit, also alle namen mit der gleichen zID sind 1 Person. Und bei der suche möchte ich alle namen finden die auf das eingegebene passen und dann dazu jewals alle namen die zu der Person gehören.