Zweifach verschachtelte Abfrage über 2 Tabellen

Tim C.

Erfahrenes Mitglied
Folgendes Problem:

Ich habe zwei Tabellen in einer MySQL Datenbank. status und fa_pass0_login. Das Layout dieser ist wie folgt
Code:
|-----------------|
| fa_pass0_login  |
|-----------------|
| nic             |
| level           |
|-----------------|

|-----------------|
| status          |
|-----------------|
| user            |
|-----------------|
Zwischen fa_pass0_login.nic und status.user besteht eine 1:n Verknüpfung (nur vom Denkansatz her, MySQL arbeitet ja nicht explizit mit solchen Verknüpfungen).

Das heisst, grob zusammengefasst, sind in der fa_pass Useraccounts gespeichert und in der status wird zu jeder Eingabe der User gespeichert, der die Eingabe gemacht hat.

Jetzt würde ich gerne aus der Tabelle status sämtliche Datensätze von all den Usern abfragen, die in der fa_pass Tabelle das gleiche Level haben, wie user xy, den ich im Script natürlich übergeben würde.

Und jetzt kommt der "Hammer", das ganze sollte auch noch unter einer MySQL 3.2.x Version laufen.

Mein Ansatz bis dato sieht folgendermaßen aus
Code:
SELECT s. * , f. *
FROM `status` s, fa_pass0_login f
WHERE s.user
IN (

SELECT nic
FROM fa_pass0_login
WHERE `level`
IN (

SELECT `level`
FROM fa_pass0_login
WHERE nic = 'comanns'
)
)
allerdings liefert mich das einen Fehler. Hat irgendwer weitere Ideen?
 
Hallo!

Meine Datenstruktur sieht wie folgt aus:

Code:
fa_pass0_login:

nic	level
1	10
2	30
3	10
4	50
5	30

user:
id	name
1	Tom
2	Tim
3	Domenik
4	Chris
5	Vitalis

Code:
SELECT user.id, user.name, fa_pass0_login.level
FROM user 
INNER JOIN fa_pass0_login 
ON user.id = fa_pass0_login.nic 
WHERE fa_pass0_login.level= (SELECT DISTINCT  fa_pass0_login.level FROM fa_pass0_login INNER JOIN user ON fa_pass0_login.nic = user.id WHERE user.name="Tim");

und erhalte damit folgende Ausgabe:
Code:
id	name	level
2	Tim	30
5	Vitalis	30

Ausprobiert mit MSSQL Server ... kannst ja mal versuchen, ob MySQL das auch mitmacht ... wars aber nicht so, dass MySQL Subselects erst ab Version 4.1 können soll?

Gruß Tom
 
Danke Tom für die Mühe, allerdings sind wir damit noch nicht ganz am Ziel.

nic ist der Klartext-Loginname, genau wie auch in user nicht über eine getrennte ID sortiert bzw gearbeitet wird. Ich habe versucht dein Query an meine Bedürfnisse anzupassen und rausgekommen ist folgendes
Code:
 SELECT `status.*` , fa_pass0_login.level, fa_pass0_login.nic
FROM `status`
INNER JOIN fa_pass0_login ON `status.user` = fa_pass0_login.nic
WHERE fa_pass0_login.level = (
SELECT DISTINCT fa_pass0_login.level
FROM fa_pass0_login
INNER JOIN user ON fa_pass0_login.nic = `status.user`
WHERE `status.user` = 'tim' )
LIMIT 0 , 30
resultiert in
Code:
#1064 - You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT  DISTINCT fa_pass0_login.level
FROM fa_pass0_login
INNER
Wenn ich eins nicht kann, dann sind das JOINS :(

Und ja, subselects gehen natürlich leider erst ab 4.x deshalb muss ich wohl auf die Joins zurückgreifen.

PS: ich musste irgendwie die Backticks um die status Sachen schustern, weil er sonst status als MySQL Keyword ansieht und dann geht glaub ich gar nix mehr. Und nein ich kann nicht einfach den Namen der Tabelle ändern ;)
 
Ok, ich habe mich jetzt nochmal versucht mit den JOINS anzufreunden, aber das ganze will einfach nicht in meinen Kopf rein. Eventuell weil die Beispiele in den Tutorials meist etwas abstrakt sind und größtenteils mit numerischen Primärschlüsseln arbeiten. Wie auch immer.

Ich möchte nochmal vereinfach die Verschachtelte Struktur darstellen, nach der ich den SELECT Befehl gerne aufbauen würde. Wenn niemand helfen kann, muss ich halt statt einem Query 3 ausführen, wäre auch nicht die Welt, aber in einer Zeile ist es halt eleganter.

- Ich habe die Variable $user als einzige "Eingabe" bzw. Information von außen.

- In der "innersten" Abfrage frage ich zu dem Usernamen das Level ab. Also in vereinfachter Ausführung
Code:
SELECT `level` FROM `login` WHERE `nic` = '$user'

- Ausgehend von diesem abgefragten Level möchte ich alle Werte von nic, also alle anderen User ausgegeben haben, die das selbe Level haben. Gehen wir also mal davon aus, das Level aus der letzten Abfrage steckt nun in $level.
Code:
SELECT `nic` FROM `login` WHERE `level` = '$level';

Und jetzt, gehen wir mal davon aus, das letzte SELECT liefert ein Array von Namen zurück, möchte ich aus der Tabelle status sämtliche Datensätze abfragen, bei denen der Wert user in dem zurückgegebenen Array vorkommt.
Code:
SELECT * FROM `status` WHERE `user` IN ('name1','name2','name3');
Wobei name1-3 natürlich nicht immer 3 Namen sein müssen sondern dynamisch aus der Abfrage zuvor kommen.

Also, wie ich es in 3 Schritten lösen kann weiss ich. Hat noch jemand evtl. eine Idee, wie es in einem Query mit Joins geht, und/oder warum der letzte Ansatz nicht ging?

Danke im Vorraus
 
Nachdem du die Abfragen aufgedröselt hast - habe ich auch die Frage verstanden :)

Dann fangen wir mal einfach an:

Zuerst verbinden wir die ersten beiden Abfragen. Dazu brauchen wir ein
SelfJoin (Die Tabelle wird mit sich selbst verküpft) Gemeinsamkeit ist das
Feld level.

Select l.nic from login as l left join login as r on l.level=r.level where r.nic = ‘$user’

So nun kommt die dritte Abfrage dran:
Hier ist ja user vom Status und nic vom login das verbindene Element.
Dann solle so was rauskommen:

Select s.user,s.id from status as s left join login as l on s.user=l.nic left join login as r on l.level=r.level where r.nic = ‘$user’

Sollte es theroretisch tun.
Alles ohne Gewähr da ich im Moment nicht vor einem Mysql Server sitze
 
Danke vielmals melmager. Hatte es auf Grund der "leichteren" Wartbarkeit mitlerweile über 20 Zeilen Code gelöst, aber ich glaube du darfst dich glücklich schätzen einen Bug im MySQL Parser gefunden zu haben. Ich zitiere
Code:
Error
There is a chance that you may have found a bug in the SQL parser. Please examine your query closely, and check that the quotes are correct and not mis-matched. Other possible failure causes may be that you are uploading a file with binary outside of a quoted text area. You can also try your query on the MySQL command line interface. The MySQL server error output below, if there is any, may also help you in diagnosing the problem. If you still have problems or if the parser fails where the command line interface succeeds, please reduce your SQL query input to the single query that causes problems, and submit a bug report with the data chunk in the CUT section below:
----BEGIN CUT----
eNpNjkFvgkAUhO/7K+bQI6y7IoqbeCCGWBMEC1aTXhR1VcwKdBet/Rn2Fxdt0/Tw8vIy37yZIEni
RGDIMWwjDCIB7njN9ME7PZLOGu1GyHCeCjyNtwLmXVWZNlJTla9pdaisCzj1emgz5rSY1+IOeFcw
V3CGIj9KheBa4YlMPtOXUKBDGeVd+5Rd7a1cn/fkNU0Qpxb8URDNLMyDJnGRF5jEb+Mw9OFSRqYT
X6BNXeqQ6fP0zlhxev/l0A4W4yiakdCPRgKysHNT2p7n9m1OHoGpVHJTw9BzU9oyNN9ip8sTVqbO
6rNZITMwUHJX41g2ubtsWWXGsKUq983ZqApl8esfKFrkm3/0H6TvkKJKXqQa6J+Nj4PUEvrhGeC2
KU9ZUZivb3m0bdw=
----END CUT----
----BEGIN RAW----

ERROR: C1 C2 LEN: 138 139 147
STR: ‘

CVS: $Id: sqlparser.lib.php,v 1.87 2003/08/13 16:05:10 nijel Exp $
MySQL: 4.0.16-max-debug
USR OS, AGENT, VER: Win MOZILLA 5.0
PMA: 2.5.3
PHP VER,OS: 4.3.4 WINNT
LANG: en-iso-8859-1
SQL: Select s.user,s.id from `status` as s left join fa_pass0_login as l on s.user=l.nic left join login as r on l.level=r.level where r.nic = ‘comanns’

----END RAW----

:)
 
Cool - ein Mysql Bug hat mir noch in meiner Sammlung gefehlt :)

Ich habe eh das Talent BUGS zu finden :-(

Edit mir fällt grade auf das du Mysql 4.x am laufen hast
dort sollten Subselects gehen
 
Zuletzt bearbeitet:
Original geschrieben von melmager
Edit mir fällt grade auf das du Mysql 4.x am laufen hast
dort sollten Subselects gehen
Leider nur hier lokal in der Entwicklung, auf dem Server läuft 3.2
Jetzt frag nicht, warum ich nicht homogen entwickle. Tu es bitte nicht :rolleyes:
 
Zurück