PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : JOIN-Problem



imm0rt4l
25-11-2004, 14:35
Hallo User,

habe eine Frage zu einem SQL-Query welches ich auf einer MS SQL-DB ausführen möchte.

Habe 2 Tabellen mit JOIN verbunden und frage alle Datensätze ab, bei denen die ID_user = x ist.

SELECT * FROM tbl_permissions left join tbl_hyperlinks on tbl_permissions.ID_hyperlink = tbl_hyperlinks.ID WHERE ID_user = x

Jetzt kann ich alle Datensätze ausgeben lassen, bei denen beide Tabellen verbunden sind und die ID_user = x ist.


Und hier mein Problem: Wie bekomme ich die Datensätze zurück, bei denen es keine Verknüpfung zwischen den Tabelleb gibt? :confused:


Wäre für eine Lösung zu meinem Problem sehr dankbar.

Gruß,
imm0rt4l

ExRevel
25-11-2004, 16:13
Hm, wie wärs hiermit? Anschaulich ist der 'ON' Bereich im JOIN doch nur wie eine WHERE Klausel. (Anschaulich, ich will das nicht an sich vergleich :) )


SELECT * FROM tbl_permissions left join tbl_hyperlinks on tbl_permissions.ID_hyperlink <> tbl_hyperlinks.ID WHERE ID_user = x


ciao Exi

elrond
25-11-2004, 16:35
ich würd's so versuchen:


SELECT * FROM tbl_permissions left join tbl_hyperlinks on tbl_permissions.ID_hyperlink = tbl_hyperlinks.ID WHERE ID_user = x and tbl_hyperlinks.ID is null

PS: SQL-Code wird lesbarer wenn man Aliasnamen für die Tabellen verwendet;) :

SELECT * FROM tbl_permissions p left join tbl_hyperlinks l on l.ID_hyperlink = p.ID WHERE p.ID_user = x and l.ID is null

Hans-Georg Normann
25-11-2004, 21:50
Also Elronds Vorschlag würde ich aufnehmen und das ganze so darstellen
SELECT *
FROM tbl_permissions p left outer join tbl_hyperlinks l on (
l.ID_hyperlink = p.ID
)
WHERE p.ID_user = xOder ist das in MS SQL nicht möglich?

Hans

elrond
26-11-2004, 06:56
wenn das Ziel wirklich war die zeilen OHNE Verknüpfung darzustellen ist das hier notwendig:


... and l.ID is null

imm0rt4l
26-11-2004, 09:56
Hallo User,

danke für die vielen Tipps, doch leider besteht mein Problem noch immer.
Kann gut sein, dass ich mich schlecht ausgedrückt habe - aus diesem Grunde habe ich eine kleine Grafik erstellt, um alle Klarheiten zu beseitigen! :p

http://tristanfischer.com/JOIN-problem_small.gif


So, was ich jetzt ausgeben möchte, sind die Datensätze der Tabelle tbl_hyperlinks, die nicht verknüpft sind.
Hier z.B.: 3, 5, 7, 8

Habe die Vorschläge von euch ausprobiert, haben leider nicht funktioniert.

Für einen Lösungsvorschlag wäre ich sehr Dankbar.


Gruß,
imm0rt4l

sticky bit
26-11-2004, 16:34
So vielleicht:


-- Sollte auf jeden Fall funktionieren ist nur ggf. etwas langsam...
SELECT *
FROM tbl_hyperlinks h
WHERE h.id NOT IN (SELECT p.id_masterlink
FROM tbl_permissions p);

-- Sollte auch funktionieren und schneller sein...
SELECT *
FROM tbl_hyperlinks h
WHERE NOT EXISTS (SELECT p.id_masterlink
FROM tbl_permissions p
WHERE p.id_masterlink = h.id);

-- Ist vielleicht sogar noch etwas schneller, musst du ausprobieren,
-- geht allerdings nicht wenn sich mehrere Datendätze in `tbl_masterlink` auf
-- eine ID beziehen, weil Single Row Subquery...
SELECT *
FROM tbl_hyperlinks h
WHERE (SELECT p.id_masterlink
FROM tbl_permissions p
WHERE p.id_masterlink = h.id) IS NULL;

Ist halt jetzt ohne irgenein gejoine. Hoffe das ist nicht wichtig, ich hab zwar mal irgendwo von so ner Möglichkeit gelesen praktisch "negativ" zu joinen aber weiss nicht mehr wo das stand oder wie das ging...

Jasper
27-11-2004, 21:05
-- Sollte auf jeden Fall funktionieren ist nur ggf. etwas langsam...
SELECT *
FROM tbl_hyperlinks h
WHERE h.id NOT IN (SELECT p.id_masterlink
FROM tbl_permissions p);


"auf jeden fall" auf jeden fall nicht. die subquery darf _keine_ NULL-werte zurückgeben.


-j

sticky bit
28-11-2004, 05:09
Mag sein dass er es gemäss irgendeines der SQL-Standards nicht darf, da muss ich ganz ehrlich gesagt passen, aber bei vielen DBMS tut er es trotzdem und wenn ich mich nicht ganz schwer täusche gehöhrt das Microsoftsche um dass es ja letztendlich geht da mit zu! ;) Mit Postgres geht es da hab ichs gerade extra noch mal probiert, an ne MS SQL komm ich jetzt von hier nicht ran aber wie gesagt da bin ich mir ziemlich sicher!
Ausserdem das was du gequoted hast, da sollten gar keine NULLs im Subquery drinne sein, zumindest geh ich anhand des Beispiels davon aus, dass keine NULL FKs da drinne sind, aber da kann ich mich täuschen...
Sieht mit dem letzten Query, den du wahrscheinlich eigentlich meintest aber genaus so aus wie eingangs erwähnt.

Jasper
28-11-2004, 09:22
Ausserdem das was du gequoted hast, da sollten gar keine NULLs im Subquery drinne sein, zumindest geh ich anhand des Beispiels davon aus, dass keine NULL FKs da drinne sind, aber da kann ich mich täuschen...
Sieht mit dem letzten Query, den du wahrscheinlich eigentlich meintest aber genaus so aus wie eingangs erwähnt.

ich meinte schon die "NOT IN"-variante. bei diesem anti-join erhält man falsche resultate, wenn NULL-werte im spiel sind. auf diese einschränkung wollte ich nur hinweisen.

auch wenn der OP schrieb, dass die lösung von elrond (left outer join) nicht funktionieren würde, sie tut es.


-j

Hans-Georg Normann
28-11-2004, 11:36
-- Sollte auf jeden Fall funktionieren ist nur ggf. etwas langsam...
SELECT *
FROM tbl_hyperlinks h
WHERE h.id NOT IN (
SELECT p.id_masterlink
FROM tbl_permissions p
WHERE NOT p.id_masterlink IS NULL);hmm, und das geht etwa nicht? (Habe es selbst nicht ausgetestet)

Hans

sticky bit
29-11-2004, 02:33
@Jasper:
Ich glaub ich weiss jetzt was du meinst:
Wenn, um bei diesem Beispiel zu bleiben in der Tabelle ` tbl_hyperlinks` in der Spalte `id` ein oder mehrere NULLs sind, dann wird der entsprechende Record auch angezeigt, wenn in der Tabelle `tbl_permissions` in der Spalte `id_masterlink` NULL Werte vorhanden sind.
Wenn du das meintest, haste recht, zumindest auf der Postgre wo ich es getestet habe geht das nicht, bei der Microsoft werde ich es bei Gelegenheit mal testen wenn ich wieder in der Firma bin, wird aber wohl genauso aussehen.
Ansowas habe ich ehrlich gesagt nicht gedacht. Wie auch immer , ne Spalte die `id` heisst lässt auf PK vermuten da gehöhren eh keine NULLs rein... :P Aber ansonsten haste recht!

imm0rt4l
06-12-2004, 10:47
Hallo User,


vielen Dank, mein Problem ist gelöst!! :D


Habe mich für diese Lösung entschieden:

SELECT *
FROM tbl_hyperlinks h
WHERE NOT EXISTS (SELECT p.id_masterlink
FROM tbl_permissions p
WHERE p.id_masterlink = h.id);
nur noch "AND p.ID_user = " & rs_user("ID")" in das 2. SELECT-Statement eingefügt und fertig ist es.

Gruß,
imm0rt4l