Marc Nilius: SQL-Befehl will nic in MySQL

Hi!

Ich habe hier einen SQL-Befhel, der in MySQL nich will. Ich meine mich zu erinnern, das MySQL keine Subselects kann, aber da ich nicht so wirklich in der Materie bin, wie kann ich diesen Befehl denn umbauen, damit er in MySQL funktioniert?

SELECT kundennr FROM kunde WHERE artikelnr ALL (SELECT DISTINCT artikelnr FROM artikel)

Danke schonmal!

Gruss,
Marc

  1. Halihallo Marc

    SELECT kundennr FROM kunde WHERE artikelnr ALL (SELECT DISTINCT artikelnr FROM artikel)

    SELECT kundennr FROM kunde JOIN artikel ON (artikelnr)

    Viele Grüsse

    Philipp

  2. Hi!

    Kenne mich Dank MySQL mit Subselects nicht wirklich aus, verstehe ich das richtig: Du willst alle Datensätze aus der kunde, die in der Spalte  artikelnr eine Nummer enthalten die in der Tabelle artikel vorkommt, oder?

    SELECT kundennr FROM kunde WHERE artikelnr ALL (SELECT DISTINCT artikelnr FROM artikel)

    Dann würde ich das mit einem LEFT JOIN machen

    SELECT t1.kundennr
      FROM kunde AS t1
    LEFT JOIN artikel AS t2
      ON t1.artikelnr = t2.artikelnr
    WHERE t2.artikelnr IS NOT NULL

    Siehe auch http://www.mysql.de/documentation/mysql/bychapter/manual.de_Deutsch.html#ANSI_diff_Sub-selects
    http://www.mysql.de/documentation/mysql/bychapter/manual.de_Reference.html#JOIN

    Grüße
    Andreas

    1. Halihallo Forumer

      [...]
      ach, ja, ach, ja, kann _mich_ mal eben wer virtuell erdrosseln, bitte? Danke.

      Viele Grüsse

      Philipp
         <!--will not be continued-->

    2. Tach zusammen!

      Kenne mich Dank MySQL mit Subselects nicht wirklich aus, verstehe ich das richtig: Du willst alle Datensätze aus der kunde, die in der Spalte  artikelnr eine Nummer enthalten die in der Tabelle artikel vorkommt, oder?

      Also, diese Abfrage ist ein Gebilde, was aus der Idee entstanden ist, die Divison der relationalen Algebra (siehe Thread von mir etwas weiter unten) in SQL umzusetzen. Die Loesung hier ist von nem Bekannten, der meint, "das muesse so funktionieren" *g*.
      Was soll sie also machen: Gebe mir eine Liste derjenigen Kunden zurueck, die schonmal jegliche Artikel gekauft haben.

      Das hier die Relation kunde heisst und nicht lieferung ist einfach ein Versehen, also eigentlich ist natuerlich lieferung als Name der Relation bedeutend richtiger.

      In kunde (aka lieferung) stehen zwei Attribute Kundennr und Artikelnr und in artikel stehen auch zwei Attribute, naemlich Artikelnr und Beschreibung (letztere ist aber uninteressant).

      Intuitiv ist artikel eine Liste aller liferbaren Artikel und kunde (aka lieferung) eine Liste, die beschreibt, welcher Kunde, welche Artikel bekommen hat (in der Realitaet sollte natuerlich lieferung auch noch Attribute wie Datum, Anzahl etc. haben, die hier aber irrelevant sind).

      Dann würde ich das mit einem LEFT JOIN machen

      SELECT t1.kundennr
        FROM kunde AS t1
      LEFT JOIN artikel AS t2
        ON t1.artikelnr = t2.artikelnr
      WHERE t2.artikelnr IS NOT NULL

      Obwohl ich nicht der Held in SQL bin, meine ich feststellen zu koennen, dass o.a. Statement dies also nicht liefert.

      Mein Statement nochmal:
      SELECT kundennr FROM kunde WHERE artikelnr ALL (SELECT DISTINCT artikelnr FROM artikel)

      Der Subselect gibt nur eine Liste aller Artikelnr zurueck. ich suche jetzt also diejenigen Kundennr in kunde (aka lieferung), wo alle Artikelnr schon nebenstehen (also nicht auf einmal, sondern im Laufe der Relation) :-)

      Ich hoffe, ich habe das Problem jetzt soweit und so verstaendlich wie moeglich beschrieben (ich bin nicht so gut im aufschreiben von sowas *g*).

      Gruss,
      Marc

      1. Hi!

        Ah so ;-)

        Das ALL war mir eh suspekt, ich wußte nicht genau was das soll. Du kannst einen Trick anwenden: Gruppiere die Lieferungen über Ihre Kunden-ID und filtere mit HAVING alle Datensätze, die COUNT(Kunden-ID) = "Anzahl aller Artikel" haben.

        Also grob sowas:

        SELECT COUNT(kundennr)
          FROM lieferung
        GROUP BY kundennr
        WHERE COUNT(kundennr)= "Anzahl Artikel"

        Dazu bräuchtest Du wohl 2 Abgragen, keine Ahnung ob das auch mit einer geht.

        Grüße
        Andreas

        1. Halloechen!

          Ah so ;-)

          Genau ... :-)

          Das ALL war mir eh suspekt, ich wußte nicht genau was das soll. Du kannst einen Trick anwenden: Gruppiere die Lieferungen über Ihre Kunden-ID und filtere mit HAVING alle Datensätze, die COUNT(Kunden-ID) = "Anzahl aller Artikel" haben.

          Also grob sowas:

          SELECT COUNT(kundennr)
            FROM lieferung
          GROUP BY kundennr
          WHERE COUNT(kundennr)= "Anzahl Artikel"

          Dazu bräuchtest Du wohl 2 Abgragen, keine Ahnung ob das auch mit einer geht.

          Soll ich jetzt mal die Katze ausm Sack lassen?
          Warum ich das Ganze versuche ist ganz einfach, es ist ne Uebungsaufgabe zur Vorlesung Datenbanksysteme.
          D.h. allerdings dann auch, dass das wohl auch in einer SQL-Anweisung geschehen sollte...

          Ich hatte mir da folgendes gedacht:

          SELECT Kundenr FROM lieferung WHERE Kundenr IN
          (SELECT Kundenr, COUNT(*) FROM lieferung GROUP BY Kundenr HAVING COUNT(*) = (SELECT DISTINCT COUNT(*) FROM artikel))

          Fuer diesen Ausdruck wurde ich aber fuer bescheuert erklaert und mir wurde der jetzt schon bekannte Ausdruck aufgetischt. Dieser wollte mir nich in den Kopf, ich wollte in in MySQL ausprobieren, das funktionierte nicht und ich eroeffnete diesen Thread.

          Aber wie ich sehe, ist deine Idee prinzipiell genau das, was ich hier auch habe...

          Gruss,
          Marc

      2. Hallo,

        Also, diese Abfrage ist ein Gebilde, was aus der Idee entstanden ist, die Divison der relationalen Algebra (siehe Thread von mir etwas weiter unten) in SQL umzusetzen. Die Loesung hier ist von nem Bekannten, der meint, "das muesse so funktionieren" *g*.

        Dann brauchst Du ein DBS, das außer JOIN und UNION auch noch DIVIDE unterstützt. Mir ist allerdings keines bekannt. Sonst geht sowas nur mit DBS-internen Funktionen.

        Beispiel im ACCESS:

        Tabelle: TeileLieferer
        Lieferer   Teil
        L1         T1
        L2         T1
        L3         T1
        L5         T1
        L1         T2
        L2         T2
        L3         T2
        L1         T3
        L2         T3
        L4         T3
        L4         T4

        Tabelle: gesuchteTeile
        Teil
        T1
        T2

        SELECT TeileLieferer.Lieferer, Count(gesuchteTeile.Teil) AS AnzTeile
        FROM TeileLieferer INNER JOIN gesuchteTeile ON TeileLieferer.Teil = gesuchteTeile.Teil GROUP BY TeileLieferer.Lieferer HAVING (((Count(gesuchteTeile.Teil))=DCount("[Teil]","gesuchteTeile")));

        Lieferer  AnzTeile
        L1        2
        L2        2
        L3        2

        viele Grüße

        Axel

        1. Hi!

          Dann brauchst Du ein DBS, das außer JOIN und UNION auch noch DIVIDE unterstützt. Mir ist allerdings keines bekannt. Sonst geht sowas nur mit DBS-internen Funktionen.

          Ich behaupte jetzt mal frech, das es wohl gehen muss, da es (siehe meine Antwort von vor 5 Minuten) eine Uebungsaufgabe an der Uni ist.

          Da mir dieses wunderhuebsche DIVIDE allerdings fehlt, hab ich ja das Problem. :-)

          SELECT TeileLieferer.Lieferer, Count(gesuchteTeile.Teil) AS AnzTeile
          FROM TeileLieferer INNER JOIN gesuchteTeile ON TeileLieferer.Teil = gesuchteTeile.Teil GROUP BY TeileLieferer.Lieferer HAVING (((Count(gesuchteTeile.Teil))=DCount("[Teil]","gesuchteTeile")));

          Grundsaetzlich erkenne ich da so einige Parallelen zu meiner Loesung (siehe auch mein Posting von vor 5 Minuten) ;-)

          Jetzt mal ganz daemlich gefragt: wieso hats denn kein DIVIDE im irgendwelchen DBS?
          Ich behaupte mal, dass zumindest mir dadurch einiges an Arbeit erspart geblieben waere ;-)

          Gruss,
          Marc

          1. Hallo,

            Jetzt mal ganz daemlich gefragt: wieso hats denn kein DIVIDE im irgendwelchen DBS?
            Ich behaupte mal, dass zumindest mir dadurch einiges an Arbeit erspart geblieben waere ;-)

            Ja, unter Garantie. Allerdings scheint man sich gerne um SQL-Statements für DIVIDE zu drücken ;-))

            http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/chap7.htm#Chap7.2.7

            viele Grüße

            Axel

  3. Halihallo Marc

    Ich habe hier einen SQL-Befhel, der in MySQL nich will. Ich meine mich zu erinnern, das MySQL keine Subselects kann, aber da ich nicht so wirklich in der Materie bin, wie kann ich diesen Befehl denn umbauen, damit er in MySQL funktioniert?

    SELECT kundennr FROM kunde WHERE artikelnr ALL (SELECT DISTINCT artikelnr FROM artikel)

    BTW: Was hat denn artikelnr in der Relation kunde zu suchen? - Ist schon so beabsichtigt,
    oder?
    Zum Problem weiter unten ([pref:t=42806&m=233979]) habe ich leider keine Tipps.
    Heute bin ich einfach zu inkompetent für alles! Herrgott, heute ist ein scheiss Tag! [1]

    [1] derartige Machtwörter sind zwar nicht sehr mein Fall und versuche sie stehts zu
        vermeiden, aber heute, ja heute, ach Schwamm drüber und schlafen geh! Scheisse ;)

    Viele Grüsse

    Philipp