Allquantor mit EXISTS

Hallo Community!

Ich lerne gerade SQL und habe ein Problem damit, den Allquantor zu realisieren. Also zB gegeben folgende 2 Relationen:

LANGUAGES (name):
(java)
(sql)

PROGRAMMERS (name, language):
(michael, java)
(frank, java)
(frank, sql)

gesucht: Welche Programmierer beherrschen alle Sprachen aus LANGUAGES?

Soweit mir bekannt gibt es den Allquantor in SQL nicht direkt, aber ich habe gelesen man kann ihn über eine “doppelte Negierung” des EXISTS-Operators realisieren. Also nach dem Motto:

…WHERE NOT EXISTS (… WHERE NOT …)

Aber ich bin bislang daran gescheitert, meine Versuche die obige Anfrage zu machen liefern mir immer eine leere Relation. Ich verstehe auch wieso, nur komme ich nicht darauf wie ich das machen muss damit es der richtigen Logik entspricht.

Also meine Frage: Wie kann ich obige Anfrage (mit Ergebnis “frank”) mittels des (NOT) EXISTS Operators realisieren? Und: Ist das wirklich die einzige Möglichkeit, oder geht es auch anders?

Vielen Dank

Wäre es möglich ein wenig SQL zu posten? Ansonsten könnte passieren, das sich das Eschaton immanentisiert und wir dir vorher nicht helfen können. :wink:

morgendliche Grüße Uwe

Du suchst nach dem Stichwort “relational division”.

Sowas in der Art hier:

SELECT name
FROM programmers
GROUP BY name
HAVING count(DISTINCT language) = (select count(*) from languages);

castorp,

Cool, an soetwas hatte ich nicht gedacht, aber es ist natürlich einleuchtend. Danke, ich werd’s mir merken!

Trotzdem möchte ich auch die Herangehensweise mittels EXIST verstehen. Also mein erster Versuch dazu sah wie folgt aus:

SELECT p.name FROM programmers p
WHERE NOT EXISTS 
(
    SELECT l.name FROM languages
    WHERE NOT (p.language = l.name)
)

Dass das nicht das gewünschte Ergebnis liefert ist mir dann klar geworden, also hab ich irgendwie soetwas versucht:

SELECT p.name FROM programmers p
WHERE NOT EXISTS 
(
    SELECT l.name FROM languages, programmers p2
    WHERE p.name = p2.name AND NOT (p2.language = l.name)
)

Aber das funzt auch nicht, und ich muss gestehen die Logik davon ist für mich derzeit noch etwas zu komplex…

Was mich jetzt beim googlen vorallem verwirrt hat: Braucht man dafür 2x ein NOT EXISTS? Denn in der Literatur, die ich vorliegen habe, wird nur das Muster:
NOT EXISTS (… NOT …)

gegeben, d.h. nur einmal das EXISTS negieren, und dann kein weiteres mal ein exists sondern einfach nur noch die Bedingung negieren…

Über ein Beispiel mittels EXISTS würde ich mich sehr freuen, die Suchergebnisse die ich im Netz dazu finden sind irgendwie immer mit mehr als 2 Relationen oder anderweitig verkompliziert, sodass ich nicht genau ersehen kann was nun das entscheidende für die Division da ist.

Vielen Dank

Ich möchte nicht spammen, aber gibt es niemanden, der mir da helfen kann? Ich komm einfach nicht drauf, wie ich das genannte Bsp mittels EXIST lösen kann. :frowning:

Ich hätt als Alternative noch:

test=*# select * from (select name, array_agg(language order by language asc) as sprachen from programmers group by name) foo where foo.sprachen = (select array_agg(name order by name asc) from languages);
 name  |  sprachen
-------+------------
 frank | {java,sql}
(1 row)

aber für exist bin ich grad zu faul …