Tabellenvergleich via NOT IN

P.Flender

Neuer Benutzer
Beiträge
4
Hallo zusammen,

ich habe 2 Tabellen mit unterschiedlichen Datensätzen. Ich möchte, dass ich die Datensätze der 1. Tabelle und die in der 2. Tabelle nicht existieren ausgeben. Es gibt ein Feld bei dem es Übereinstimmungen geben könnte. Ich hatte mir 2 Testtabellen gebaut, da hat es mit folgendem Befehl geklappt:

select * from table1 where field1 not in (Select field2 from table);

Mit den richtigen Tabellen filtert er mir aber alle Datensätze der Table1. Was fehlt dort in meiner Überlegung? Braucht es einen index, primary key, etc. damit das funktioniert?
 
Werbung:
hilft Dir das weiter?

Code:
postgres=# create table t1 (a int, b int, c int);
CREATE TABLE
postgres=# create table t2 (a int, b int, c int);
CREATE TABLE
postgres=# insert into t1 values (1,1,1);
INSERT 0 1
postgres=# insert into t1 values (2,2,2);
INSERT 0 1
postgres=# insert into t2 values (2,2,2);
INSERT 0 1
postgres=# insert into t2 values (3,3,3);
INSERT 0 1
postgres=# select * from t1 except select * from t2;
 a | b | c 
---+---+---
 1 | 1 | 1
(1 row)

postgres=# select * from t2 except select * from t1;
 a | b | c 
---+---+---
 3 | 3 | 3
(1 row)

postgres=#
 
Table 1(1831 Einträge) hat id (int) und PNummer varchar(28), Table 2(2051) hat id(int) und DNummer varchar(28). Ich möchte wissen ob es PNummern gibt die nicht in DNummern vorkommen.
1675404785132.png

1675404769652.png
 
Dann noch mal laaaangsam zum mitdenken...

Code:
postgres=# drop table t1;
DROP TABLE
postgres=# drop table t2;
DROP TABLE
postgres=# create table t1 (id int generated always as identity primary key, pnummer varchar(28));
CREATE TABLE
postgres=# create table t2 (id int generated always as identity primary key, dnummer varchar(28));
CREATE TABLE
postgres=# insert into t1 (pnummer) select * from generate_series(1,10)s;
INSERT 0 10
postgres=# insert into t2 (dnummer) select * from generate_series(5,15)s;
INSERT 0 11


-- was hat t1, was t2 nicht hat?
postgres=# select pnummer from t1 except select dnummer from t2;
 pnummer 
---------
 2
 4
 3
 1
(4 rows)

-- was hat t2, was t1 nicht hat?
postgres=# select dnummer from t2 except select pnummer from t1;
 dnummer 
---------
 13
 11
 12
 15
 14
(5 rows)

--was haben beide gemeinsam?
postgres=# select pnummer from t1 intersect select dnummer from t2;
 pnummer 
---------
 9
 10
 7
 6
 5
 8
(6 rows)

postgres=#
 
Meinst Du etwa sowas?

Code:
SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.field = t2.field WHERE t2.field IS NULL;

Diese Abfrage gibt alle Datensätze aus der Tabelle 1 zurück, für die es keine Übereinstimmungen im Feld in Tabelle 2 gibt.
oder um alle Felder in Tabelle zwei zu überprüfen wäre das folgende Abfrage:

Code:
SELECT t1.*
FROM table1 t1
WHERE NOT EXISTS (
  SELECT 1
  FROM table2 t2
  WHERE t1.field1 = t2.field1
  AND t1.field2 = t2.field2
  ...
  AND t1.fieldN = t2.fieldN
);
 

Ist der Code von akretschmer nicht für PostgreSQL? Ich glaube Du möchtest diesen aber eher in MySql einsetzen? Bin kein Experte, aber versuchs mal so:


Code:
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;

CREATE TABLE t1 (
  id int auto_increment primary key,
  pnummer varchar(28)
);

CREATE TABLE t2 (
  id int auto_increment primary key,
  dnummer varchar(28)
);

INSERT INTO t1 (pnummer) SELECT * FROM (SELECT @rownum := @rownum + 1 FROM (SELECT @rownum := 0) r, (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10) t) t;

INSERT INTO t2 (dnummer) SELECT * FROM (SELECT @rownum := @rownum + 5 FROM (SELECT @rownum := 0) r, (SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15) t) t;

-- was hat t1, was t2 nicht hat?
SELECT pnummer FROM t1 WHERE pnummer NOT IN (SELECT dnummer FROM t2);

-- was hat t2, was t1 nicht hat?
SELECT dnummer FROM t2 WHERE dnummer NOT IN (SELECT pnummer FROM t1);

-- was haben beide gemeinsam?
SELECT pnummer FROM t1 WHERE pnummer IN (SELECT dnummer FROM t2);
 
Das mag ja stimmen, bringt ihm allerdings nichts, wenn er das in phpmyadmin eingibt und besagten Fehler erhält, weil dieser den Code einfach etwas pingeliger interpretiert.
 
Werbung:
Was fehlt dort in meiner Überlegung?

#1222 - Die verwendeten SELECT-Befehle liefern unterschiedliche Anzahlen von Feldern zurück

In Deiner Überlegung fehlt zunächst, dass Du Dein fehlerhaftes Statement nicht zeigst.
select * from table1 where field1 not in (Select field2 from table);
funktioniert
Code:
select * from table1 where field1 not in (Select field1, field2 from table);
würde wahrscheinlich den gleichen Fehler werfen, weil
field1 = 1 Feld
und
field1, field2 = 2 Felder
Beide Ausdrücke müssen aber gleich viele Felder enthalten. Die Fehlermeldung ist eigentlich relativ präzise.

Was für eine hilfreiche Antwort auch fehlt, ist die Nutzung von Text. Also alphanumerische Zeichen, die man per Copy/Paste von seinem Tool in den Eröffnungspost überträgt.
Wenn Du zukünftig bessere und schnellere Antworten erhalten möchtest, poste keine Bilder, außer Du bist in einem Forum für Malerei oder Erotik oder beides.

@Kopernikus und @P.Flender
in oder not in sollte man eigentlich nicht verwenden, ebensowenig einen JOIN mittels Where Clause- zumindest wenn man mit viel Datensätzen arbeitet, oft ist ein richtiger JOIN besser geeignet und besserer Stil sowieso. Stil ist am Ende nicht entscheidend, aber für Anfänger klarer.

Hier ist ein Beispiel:
 
Zurück
Oben