SQL: Datensätze finden, die NICHT in der n:m Tabelle sind

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

SQL: Datensätze finden, die NICHT in der n:m Tabelle sind

Beitrag von Aliobaba »

Hallo,

ich habe die "Tabelle A", die "Tabelle B" und die "Tabelle NM" (beinhaltet n:m Beziehungen)

Wie finde ich in der "Tabelle A" alle Einträge, die in der "Tabelle NM" nicht vorkommen, also keinerlei n:m Beziehungen haben?

Konkret: "Tabelle A" sind Texteinträge, "Tabelle B" sind Schlagworte. Beliebig viele Texteinträge können mit beliebig vielen Schlagworten verknüpft werden (dazu dient die "Tabelle NM"). Jetzt möchte ich gerne die Texteinträge suchen, denen kein(!) Schlagwort zugeordnet ist; deren Primärschlüssel also in der "Tabelle NM" gar nicht vorkommt.
Ich habe dies bisher gelöst, indem ich jeden Texteintrag in "Tabelle A" dahingehend der Reihe nach abgefragt habe, wieviele Schlagworte mit ihm verbunden sind.
(Falls Ergebins = 0 habe ich einen der gesuchten Datensatz gefunden .. usw. bis jeder Texteintag abgefragt ist).
Dies erscheint mir aber gelinde gesagt "wenig elegant" :oops: . Da sollte es doch auch ein SQL-Statement geben, das dieses Problem lösen kann.

Ich finde es aber nicht. Kann mir jemand helfen?

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Eb »

Code: Alles auswählen

SELECT a.texteintrag
FROM a LEFT OUTER JOIN nm
ON
 (
      a.identnr = nm.identnr
  AND a.fi_nr   = nm.fi_nr
 )
WHERE  nm.texteintrag IS NULL;

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Aliobaba »

Wow!
...das ging aber schnell! Werde es gleich 'mal ausprobieren.
Danke Eb!!! :)
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Aliobaba »

Sorry: Was ist:
a.fi_nr = nm.fi_nr ?
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Eb »

das sind Felder über welche die beiden Tabellen verknüpft sind.
(war ein Real-Life-Beispiel ...)

Wenn du die beiden Tabellen nur über das Feld id eindeutig verknüpfst würde es so aussehen:

Code: Alles auswählen

SELECT a.texteintrag
FROM a LEFT OUTER JOIN nm
ON
 (
      a.id = nm.id
 )
WHERE  nm.texteintrag IS NULL;

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Aliobaba »

....hm...

Ich habe versucht, diese 2. Version umzusetzen; Es werden aber (im SQLite-Manager) ALLE ID's der "Text-Tabelle angezeigt.

Folgende(r Versuch der) Umsetzung Deines 2. Vorschlags:
SELECT tText.rID FROM tText LEFT OUTER JOIN tC ON ( tText.rID = tC.rID ) Where tC.rFKText IS NULL;

Aliobaba

zur Datenbankstruktur:
"tText" ist die Texttabelle - "tSchlagw" ist die Schlagworttabelle - "tC" ist die "Verknüpfungstabelle"
->->->

CREATE TABLE "tText"
(
"rID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
"rTitel" VARCHAR(90) NOT NULL,
"rText" TEXT,
"rHinweis" TEXT,
"rFKRubrik" INTEGER DEFAULT '1', "rDatumerstellt" CHAR, "rDatumgeaendert" CHAR, T1 TEXT, T2 TEXT, T3 TEXT, T4 TEXT, T5 TEXT,
FOREIGN KEY(rFKRubrik) REFERENCES tRubrik(rID) ON DELETE NO ACTION
)

CREATE TABLE "tSchlagw"
(
"rID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
"rSchlagw" VARCHAR (51) NOT NULL
, S1 TEXT, S2 TEXT, S3 TEXT, S4 TEXT, S5 TEXT)

CREATE TABLE "tC"
(
"rID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
"rFKText" INTEGER NOT NULL ,
"rFKSchlagw" INTEGER NOT NULL , C1 TEXT, C2 TEXT, C3 TEXT, C4 TEXT, C5 TEXT,
FOREIGN KEY(rFKText) REFERENCES tText(rID) ON DELETE CASCADE,
FOREIGN KEY(rFKSchlagw) REFERENCES tSchlagw(rID) ON DELETE CASCADE
)

"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Eb »

Ich kenne mich jetzt mit SQLite nicht aus (mein Beispiel war Informix).

Dein Join
tText.rID = tC.rID
kommt mir aber seltsam vor.


Werden die beiden Tabellen dadurch wirklich richtig verknüpft?

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Aliobaba »

DANKE, Eb!! :)

So:
ON ( tText.rID = tC.rFKText )
musste es laute; dann funktioniert es!

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Eb »

na dann, noch ein schönes Wochenende,
Eb

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: SQL: Datensätze finden, die NICHT in der n:m Tabelle sin

Beitrag von Aliobaba »

... werde ich haben - und du bist erheblich schuld daran :D (Nochmals: Danke!)
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Antworten