Welche ID steht nicht in einer anderen Tabelle

gurbelunder

SQL-Guru
Beiträge
136
Moin Leute,

heute stehe ich mal auf dem Schlauch:

Ich habe zwei Tabellen:
[CODE
DOCUMENT
------------------------
ID, Name, Dateigröße

DOCUMENTCUSTOMFIELDVALUE
-------------------------------------------------
ID(aus der DOCUMENT), Name, Typ, ...
[/CODE]

Ich möchte nun prüfen, welche ID's in der DOCUMENTCUSTOMFIELDVALUE auftauchen, die nicht in der DOCUMENT stehen. Also habe ich zwei verschiedene Abfragen, die doch eigentlich dasselbe Ergebnis bringen sollten?

Nummer 1 mit MINUS:
Code:
select count(*) from
(
select a.ID from DOCUMENTCUSTOMFIELDVALUE a
MINUS
select b.ID from DOCUMENT b
);

Nummer 2 mit JOIN (diese braucht auf jedenfall länger):
Code:
select count(*) from
(
select a.ID from DOCUMENTCUSTOMFIELDVALUE a, DOCUMENT b where a.ID NOT LIKE b.ID
);

Ich habe absichtlich das Zählen drum herum gebunden, weil eigentlich bei beiden Abfragen das gleiche raus kommen sollte, oder?

Danke euch und Grüße,
David
 
Werbung:
Moin Leute,



Ich möchte nun prüfen, welche ID's in der DOCUMENTCUSTOMFIELDVALUE auftauchen, die nicht in der DOCUMENT stehen. Also habe ich zwei verschiedene Abfragen, die doch eigentlich dasselbe Ergebnis bringen sollten?


Ich habe absichtlich das Zählen drum herum gebunden, weil eigentlich bei beiden Abfragen das gleiche raus kommen sollte, oder?

Danke euch und Grüße,
David


Dein zweites richt nach Cross Join. Was das MINUS in Oraggle macht weiß ich nicht genau, vermutlich sowas wie EXCEPT.
So wie Du fragst kommt nicht dasselbe bei beiden raus, stimmts? vermutlich beim zweiten mehr, oder?

Ich würde es so machen:

Code:
test=*# create table t1 (id int);
CREATE TABLE
test=*# create table t2 (id int);
CREATE TABLE
test=*# insert into t1 values (1);
INSERT 0 1
test=*# insert into t1 values (2);
INSERT 0 1
test=*# insert into t1 values (3);
INSERT 0 1
test=*# insert into t2 select * from t1;
INSERT 0 3
test=*# insert into t2 values (4);
INSERT 0 1
test=*# select distinct id from t2 except select distinct id from t1;
 id
----
  4
(1 row)
 
Wenn ich deine EXCEPT Syntax sehe, sieht das wie MINUS aus. Kurz beschrieben: beide haben eine Menge, es werden die Datensätze der zweiten Unterabfrage von der ersten Unterabfrage "abgezogen" und ausgegeben.

Warum das ganze? Dahinter steckt eine Software mit Produktiv- und Testinstanz. Wir wollen Prod Daten ins Test System spielen, aber auf dem Feld ID der DOCUMENTCUSTOMFIELDVALUE liegt ein Foreign Key auf die ID in der DOCUMENT Tabelle. Der Constraint hupt beim einspielen, es wären Datensätze in die DOCUMENTCUSTOMFIELDVALUE einzufügen, die in der DOCUMENT nicht vorkommen.

Wenn ich die MINUS Abfrage auf der produktiven Seite ausführe, erhalte ich als Ergebnis 0. Schon seltsam......
 
Da du bei
Code:
select a.ID from DOCUMENTCUSTOMFIELDVALUE a
kein DISTINCT verwendest müssten doch manche IDs mehrfach zurück geliefert werden (wenn es nicht so wäre würde die 1:n Beziehung keinen Sinn machen). Wenn du jetzt mit MINUS oder EXCEPT jede existierende ID einmal filterst bleibt noch immer was übrig.
 
Ah sry Blödsinn. EXCPET filtert tatsächlich alle IDs.

Der CROSS JOIN ist wirklich dein Problem, nimm FROM b LEFT JOIN a
 
Den DISTINCT hatte ich dann noch nachträglich eingebaut. Mein Problem ist schon alleine, dass das Statement mit dem Minus innerhalb von Sekunden durchläuft, der Join aber Stunden braucht. Über Nacht laufen lassen und noch nicht fertig, weil die Nase einen Full Table Scan macht trotz Foreign Key Constraint.
 
Werbung:
Dein CROSS JOIN liefert einfach soviele Datensätze und braucht deshalb so lange. Bei 1000 Datensätzen pro Tabelle wärst du schon bei 1 Mio Zeilen. Du wolltest vermutlich einen INNER JOIN.
 
Zurück
Oben