BlueFish: Wie kommt man jemals auf dieses SQL-Statement?

Hi!

Also es geht um ein Beispiel aus einer Klausur, nicht aus der Praxis, aber vielleicht kann mir trotzdem jemand helfen:

Gegeben folgendes DB-Schema:

Lieferant(LNr, LName, LStadt)
Ware(WNr, Bezeichnung, Preis)
Kunde(KNr, KName, KStadt)
Auftrag(LNr, WNr, KNr, Menge)

Nun soll ein SQL-Statement geschrieben werden das die Namen der Kunden ausgibt, die von _allen_ aus München stammenden Lieferanten beliefert werden.

Eine Lösung dazu habe ich auch - sie lautet:

SELECT KName FROM Kunde WHERE NOT EXISTS(
    SELECT * FROM Lieferant WHERE LStadt = 'München' AND NOT EXISTS(
        SELECT * FROM Auftrag WHERE Auftrag.KNr = Kunde.KNr AND Auftrag.LNr = Lieferant.LNr));

Und meine Frage: Wie um Gottes Willen kommt man denn darauf? Ein alternativer Lösungsvorschlag mit NOT EXISTS und NOT IN ist auch noch angegeben, aber auf den bin ich ebensowenig gekommen.

Ich hab irgendwie herumprobiert mit gleich mal alle Kunden holen die von Lieferanten aus München beliefert werden und dann wollte ich irgendwie mit NOT EXISTS diejenigen wieder abziehen, wo nicht derselbe Kunde mit Lieferanten aus München beliefert wird - aber nunja, das hat jedenfalls nicht geklappt, aber auf die obenstehende Lösung wäre ich beim besten Willen auch nicht gekommen.

Grüße
BlueFish

  1. Hallo,

    mithilfe von ALL (ANY, SOME, ALL) sollte es sogar noch einfacher gehen.

    Das hängt aber unter Umständen davon ab, ob es von deinem Datenbanksystem unterstützt wird.

    Zur Illustration solltest du vielleicht auch einfach mal Beispieldaten geben, dann wird das gleich viel plastischer und begreifbarer. Also, Eingabedaten und gewünschte Ausgabe/Ergebnis.

    Ciao, Frank

    1. Hallo,

      also ALL ist eigentlich erlaubt, dürfte also auch verwendet werden.

      Mit den Beispieldaten aus der Klausurangabe kommt gar kein Ergebnis mehr raus, es gibt keinen Kunden der von allen Lieferanten aus München beliefert wird. Ich hab dann zum Herumspielen selber einen eingefügt, aber ganz schlau werde ich trotzdem nicht, ich könnte das Bsp selber nicht lösen :-(

      Hier die Daten:

      Lieferant:
      Lieferant

      Ware:
      Ware

      Kunde:
      Kunde

      Auftrag:
      Auftrag

      Wobei die Kunden-Relation in diesem Beispiel ja eigentlich nicht benötigt wird, aber der Vollständigkeit halber hab ich sie trotzdem mitgeschickt.

      Der Datensatz mit Menge 99 in Auftrag ist von mir eingefügt worden zum Testen (auch erkennbar am kleingeschriebenen "k4"), dann sollte nämlich als Ergebnis korrekterweise Kunde "Wurm" herauskommen.

      Grüße
      BlueFish

  2. Hello,

    Und meine Frage: Wie um Gottes Willen kommt man denn darauf? Ein alternativer Lösungsvorschlag mit NOT EXISTS und NOT IN ist auch noch angegeben, aber auf den bin ich ebensowenig gekommen.

    Routine! Wie bei so vielem im Softwareumfeld, einfach Erfahrung und ein Auge dafür. In SQL führen immer viele Wege ans Ziel, wenn man etwas Erfahrung gewinnt findet man zumindest einen, wenn man viel Erfahrung hat eröffnen sich Spielräume und man kann Lösungen vergleichen.
    Wie Frank schon angemerkt hast, mit ALL oder ANY solltest du ebenso schnell an dein Ziel kommen, aber das ist abhängig von der Datenbank. Für den Augenblick reicht es sich zu überlegen: Was macht denn "Alle Lieferanten" aus. Wenn wir davon ausgehen, dass die Datenbank "alle" nicht unterstützt, dann bleibt uns nur übrig mal danach zu gucken ob sie das Gegenteil unterstützt, also "keinen". OK, also mit dem Wissen, dass es NOT EXISTS gibt (EXISTS für alle reicht ja nicht, das ist ja nur ein "es gibt mind. einen") brauchen wir nun noch die rein logische und SQL-unabhängige Frage zu beantworten, wie man denn "alle Lieferanten" mit Hilfe von "existiert nicht" bauen können. Na ja, OK, also wir wollen alle Kunden, bei denen alle Lieferanten vertreten sind. D.h. wir wollen alle Kunden, bei denen es keinen Lieferanten gibt, der nicht vertreten ist. Und das können wir schreiben, genau das steht in deinem Statement.
    Klingt trivial und trotzdem kommt man nicht drauf. Für eine Klausur eine unbefriedigende Lösung, aber leider braucht man wirklich Routine...

    MfG
    Rouven

    --
    -------------------
    Computer programming is tremendous fun. Like music, it is a skill that derives from an unknown blend of innate talent and constant practice. Like drawing, it can be shaped to a variety of ends: commercial, artistic, and pure entertainment. Programmers have a well-deserved reputation for working long hours but are rarely credited with being driven by creative fevers. Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination, but because their imagination reveals worlds that others cannot see. -- Larry OBrien and Bruce Eckel in Thinking in C#
    1. Hi,

      vielen Dank für Deine Antwort. Vom logischen her finde ich das Ganze ja noch halbwegs verständlich, auf NOT EXISTS bin ich ja selber noch gekommen, aber das ganze Statement hätte ich niemals hingekriegt. Mittlerweile bin ich mit dem Ding auch nur mehr verwirrt, ehrlich gesagt.

      Ich dachte eigentlich, ich hätte das ALL verstanden, aber damit bekomme ich es auch nicht hin. Kann mir einer von Euch noch einmal kurz die Funktionsweise von ALL erklären bitte? Irgendwie komme ich jetzt gar nicht mehr weiter :-(

      Vielleicht sollte ich einfach mit leichteren Übungsbeispielen weitermachen, aber ich habe keine mehr (jedenfalls nicht mit Lösung), und das Ding lässt mir auch keine Ruhe mehr jetzt.

      Grüße
      BlueFish