Frage zu einer SQL Formulierung mit not exist

Schönen abend,

bereite mich gerade auf eine Prüfung in Datenbanksystemen vor und verstehe eine Aufgabe bzw. die Lösung nicht. Es geht darum, alle Studenten zu finden, die auch alle Vorlesungen gehört haben.
In der Relation hören stehen VorlNr und MatrikelNr;
In der Relation Student die MatrikelNr und Name;
In der Relation Vorlesungen die VorlNr;

Ich verstehe nicht wie die Auswertung insb mit dem not exist funktionieren soll…

select s.MatrNr, s.Name from Studenten s
where not exists (select * from Vorlesungen v
where not exists (select * from hoeren h where h.VorlNr = v.VorlNr
and h.MatrNr = s.MatrNr)
);

Vielen Dank schonmal!

Tut mir leid, in dem SQL-Dialekt, mit dem ich arbeite, gibt es kein exist.
Für mich sieht das aber so aus, als ob dort die Studenten gesucht werden, die NICHT alle Vorlesungen besucht haben.

Jedenfalls werden ja in den NOT EXIST-Ausdrücken verschachtelte Unterabfragen ausgeführt, das ist Dir klar?

Ingo

Hallo hansdampf66,

ich versuche es mal mit meinen Worten zu erläutern, hierzu Beispieldaten:

Tabelle student:
1 Hans
2 Willi
3 Jens

Tabelle vorlesung:
11
12
13

Tabelle hoeren:
11 1
11 2
12 2
12 3
13 2

Zunächst den innersten Select:

  1. Hier werden alle Datensätze der ‚hören‘ Tabelle selektiert, bei denen die VorlesungsNr mit der VorlesungsNr aus der Tabelle ‚vorlesung‘ und die MatrNr mit der MatrNr aus der Tabelle ‚student‘ übereinstimmt. Hier sind die Verknüpfung zwischen den Tabellen untereinander definiert. Der Select liefert alle Datensätze aus der Tabelle ‚hoeren‘, bei denen diese Bedingungen erfüllt sind.

Nun den mittleren Select:
2) Es werden alle Datensätze aus der Tabelle ‚vorlesung‘ selektiert, bei denen kein Ergebnis aus 1) geliefert wurde. Daher werden hier alle Vorlesungen selektiert, die nicht von allen Studenten besucht wurden.

Nun den äußeren Select:
3) Es werden nun alle Studenten selektiert, bei denen kein Ergebnis aus 2) geliefert wurde.
Da 2) alle Vorlesungen liefert die nicht von allen Studenten besucht wurden, erhält man daher alle Studenten die alle Vorlesungen besucht haben (Im Beispiel Willi).
Würde man hier ein „exists“ statt dem „not exists“ angeben, erhält man alle Studenten, die nicht alle Vorlesungen besucht haben (Im Beispiel Hans und Jens).

Ich hoffe, ich konnte es einigermaßen verständlich erläutern.

Gruß Jürgen

Hallo Jürgen,

vielen Dank für deine ausführliche Antwort, die hat mich auf jeden Fall weitergebracht. Das einzige was ich nun nicht ganz verstehe ist die Funktion des exists Operator:
Eig liefert der exist ja false, wenn die Menge von Tupeln in der Unteranfrage leer ist. Aber nach der innersten Anfrage (deine (1)) habe ich doch eine Tabelle mit lauter VorlNr und den korrespondierenden Hörern, dazu noch unsortiert. Wie kommt der innerste not exist jetzt darauf, dass die Menge der Unteranfrage leer ist?
Sprich dein Satz unter (2): Daher werden hier alle Vorlesungen selektiert, die nicht von allen Studenten besucht wurden.
Wie ist das im System definiert bzw woher weiß es durch das not exist dass nicht alle die VL hören?

Nochmals vielen Dank!

Grüße,

Kai

Um es vielleicht verständlicher auszudrücken. Ich verstehe nicht, wieso die Bedingung herrscht, dass ein Student alle(!) Vorlesungen hören muss.
Meinem Verstädnis nach wählt die Unteranfrage (2) doch die Vorlesungen aus, die von niemanden gehört werden bzw. nicht existieren. Da reicht es doch sobald einer die hört…

Schönen abend,

bereite mich gerade auf eine Prüfung in Datenbanksystemen vor
und verstehe eine Aufgabe bzw. die Lösung nicht. Es geht
darum, alle Studenten zu finden, die auch alle Vorlesungen
gehört haben.

In der Relation hören stehen VorlNr und MatrikelNr;

In der Relation Student die MatrikelNr und Name;

In der Relation Vorlesungen die VorlNr;

Ich verstehe nicht wie die Auswertung insb mit dem not exist
funktionieren soll…

select s.MatrNr, s.Name from Studenten s

where not exists (select * from Vorlesungen v

where not exists (select * from hoeren h where
h.VorlNr = v.VorlNr

and h.MatrNr = s.MatrNr)

);

Das Problem ist, dass es in SQL kein richtiges
Konstrukt für Fälle wie „Studenten, die ALLE Vorlesungen besuchen“ gibt. Es gibt zwar ein
„es gibt“ in SQL (exists), aber leider kein
„für alle“. Man kann den Effekt von „für alle“
aber durch Verwendung von „es gibt“ und Verneinung
simulieren:
„für alle gilt“ == „es gibt keinen, für den nicht gilt“

Daher arbeitet man mit einer doppelten Verneinung
und sucht nach „Studenten, für die NICHT gilt, dass
sie mindestens eine Vorlesung NICHT besuchen“.
Ein Student, der bei keiner Vorlesung fehlt,
besucht alle Vorlesungen.
Genau das macht das obige SQL-Statement.

Frage ist schon beantwortet. Sorry, hatte die Tage keine Zeit meine Mail zu beantworten.

Hallo,
das ist wie eine doppelte Verneinung zu verstehen.
Man sucht also Studenten, die nicht eine Vorlesung haben, die sie nicht besucht haben. Da in „hören“ aber nur die Matrikel-Nummern stehen, kann nur über diese abgefragt werden anstatt über die Studenten-Nr. o.ä…
Gruß
Erhard

Schönen abend,

bereite mich gerade auf eine Prüfung in Datenbanksystemen vor
und verstehe eine Aufgabe bzw. die Lösung nicht. Es geht
darum, alle Studenten zu finden, die auch alle Vorlesungen
gehört haben.

In der Relation hören stehen VorlNr und MatrikelNr;

In der Relation Student die MatrikelNr und Name;

In der Relation Vorlesungen die VorlNr;

Ich verstehe nicht wie die Auswertung insb mit dem not exist
funktionieren soll…

Vielen Dank an alle, die mir eine hilfreiche Antwort geliefert haben. Am ende ist es mir dann auch eingeleuchtet :wink: (Stimmt, hatte mal wo gelesen dass es eben den Allquantifizierer in SQL nicht gibt)

Hallo,
Sorry, verstehe ich auch nicht

  • ich würde es auch anders schreiben.
    z.B. die 3 Tabellen joinen.
    Viel Glück noch
    Wolfgang