jüla: Bekomme Abfrage nicht hin

Guten Morgen,

ich bräuchte mal eure Hilfe bei einer Abfrage, die ich nicht hinbekomme.

Tabelle bucher mit id, titel, jgst
Tabelle bücherstapel mit id, jgst, name
Tabelle buch_in_stapel mit id, buchid, stapelid

Was ich nicht hinbekomme ist folgende Abfrage: Alle Bücher einer JgSt, die nicht in dem Stapel mit der stapelid=1 sind.

Das beste, was ich hinbekomme habe ist:

select *
from bucher
join stack on bucher.JgSt=bücherstapel.JgSt and bücherstapel.id=1
join buch_in_stapel on buch_in_stapel.stapelid=1 and
buch_in_stapel.buchid!=bucher.id

Das liefert mir aber zuviel Ergebnisse.

Hat jemand einen Vorschlag?

  1. Mahlzeit jüla,

    Was ich nicht hinbekomme ist folgende Abfrage: Alle Bücher einer JgSt, die nicht in dem Stapel mit der stapelid=1 sind.

    SELECT b.*  
      FROM bucher         AS b  
      JOIN buch_in_stapel AS bis ON (b.id = bis.buchid AND bis.stapelid <> 1)  
     WHERE b.jgst = :deinwert
    

    Das beste, was ich hinbekomme habe ist:

    select *

    Du holst Dir also *alles* (nicht nur die Daten der Bücher) - willst Du das *wirklich*?

    from bucher
    join stack on bucher.JgSt=bücherstapel.JgSt and bücherstapel.id=1

    Was genau ist denn jetzt "stack"? Falls es sich dabei um den "bücherstapel" handelt: ich hätte jetzt gedacht, dass die Tabelle "buch_in_stapel" die n:m-Zuordnung zwischen den Tabellen "bucher" und "bücherstapel" ist - ist das nicht so? Und wieso verknüpfst Du die beiden Tabellen über die "JgSt", du willst doch nur die Bücher einer bestimmten "JgSt", nicht aber die Bücherstapel? Oder doch? Außerdem legst Du hier als Bücherstapel-ID die 1 fest ... ich dachte, Du willst gerade diesen Stapel mit der ID = 1 *nicht*?

    Mir scheint, dass entweder Deine Aufgabenstellung nicht ganz klar ist oder Du eigentlich gar nicht so richtig weißt, was Du tust. :-)

    Hat jemand einen Vorschlag?

    Ja: beschreibe die Abhängigkeiten der Tabellen voneinander (Fremdschlüsselbeziehungen und *fachliche* Bedeutung der Tabellen und Spalten). Anschließend erkläre bitte einmal detailliert, was Du *fachlich* willst.

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
  2. Hallo jüla,

    Tabelle bucher mit id, titel, jgst
    Tabelle bücherstapel mit id, jgst, name
    Tabelle buch_in_stapel mit id, buchid, stapelid

    Heißt due Tabelle jetzt stack, bucherstapel oder bücherstapel?

    Was ich nicht hinbekomme ist folgende Abfrage: Alle Bücher einer JgSt, die nicht in dem Stapel mit der stapelid=1 sind.

    select *
    from bucher
    join stack on bucher.JgSt=bücherstapel.JgSt and bücherstapel.id=1
    join buch_in_stapel on buch_in_stapel.stapelid=1 and
    buch_in_stapel.buchid!=bucher.id

    Das liefert mir aber zuviel Ergebnisse.

    VIelleicht liegts auch nur daran, dass du nach gleich, statt nach ungleich 1 fragst???

    Was bedeutet eigentlich jgst?
    Wozu brauchst du bei dieser Abfrage die Tabelle Buch_in_stapel? Müsste nicht Folgendes schon alles liefern, was du brauchst:

    SELECT * FROM bucher a, bucherstapel b WHERE a.jgst = b.jgst AND b.id != 1

    Damit hast du alle Bücher zu einer oder mehreren jgst, deren Stapelnummer nicht 1 ist. Wenn du eine bestimmte jgst willst, musst noch eine Bedingung dafür einfügen.

    Vielleicht habe ich aber auch noch nicht alles verstanden.

    ciao
    romy

  3. moin,

    Das liefert mir aber zuviel Ergebnisse.
    Hat jemand einen Vorschlag?

    ergänzend zu dem, was dir Ekki und rommy gesagt haben, will ich dich auf eine andere problematik hinweisen, "joins sind böse". natürlich sind sie das nicht wirklich, aber man sollte sich diesen grundsatz merken, da er genau bei dem problem hilft, welches du gerade hast. in rdbms werden die jeweiligen informationen auf die verschiedenen tabellen aufgeteilt. benötige ich eine bestimmte abfrage, so muss ich mir alle tabellen zusammensuchen, die bezüglich der abfrage relevante informationen enthalten. die meisten würden das eben über joins machen. joins sind aber nicht die einzige möglichkeit tabellen miteinander in verbindung zu bringen. man muss schon mit bedacht entscheiden, wann man was einsetzt.

    es gibt unterschiedliche beziehungstypen zwischen den tabellen, man spricht hier von 1:1, 1:n oder auch n:m beziehungen, die entsprechend über die jeweiligen tabellen abgebildet werden. so hast du aller wahrschenlichkeit nach zwischen den tabellen bucher & bücherstapel (noch ein tipp, vermeide buchstaben wie ü in objektnamen) eben eine solche n:m beziehnug. ausgesprochen sagt man, ein buch kann in mehrere stapeln sein, ein stapel kann mehrere bücher haben. das macht mich ein wenig stutzig, weil ein buch sollte eigentlich nicht in verschiedenen stapeln auftauschen, aber das hängt stark davon ab, was genau du damit abbildest. muss man noch mal schauen.

    wie auch immer, für deine problematik ist das erst mal egal. wenn wir nun eine solche n:m beziehung haben, dann verfielfachen sich durch die verwendung der joins die datensätze bei einer abfrage. um dies zu vermeiden rate ich immer, erst mal die richtige basis (anzahl) der datensätze aufzubauen. in deinem falle willst du alle bücher haben, das wäre dann auch deine "basistabelle".

    SELECT COUNT(*)
    FROM bucher
    ;

    nun kommt die spannende frage, wie schließe ich die bücher aus, die ich nicht haben will, ohne joins zu verwenden. die antwort darauf sind sogenannte korrelierte unterabfragen. ob man diese verwenden kann, hängt ein wenig von deinem dbms und der version ab, ich vermute mal, du benutzt mysql, fragt sich nur noch in welcher version ? zumal auch noch nicht ganz klar ist, was die spalte "jgst" darstellt und warum sie in zwei tabellen vorkommt und wie die drei tabellen miteinander verbunden sind, ich kann also nur vermuten.

    SELECT COUNT(*)
    FROM bucher b
    WHERE b.jgst = hier_ein_bestimmer_wert
    AND NOT EXISTS (SELECT NULL
                    FROM buch_in_stapel bis
                    WHERE bis.buchid b.id
                    AND stapelid = 1
                   )
    ;

    Ilja

    1. Hello,

      es gibt unterschiedliche beziehungstypen zwischen den tabellen, man spricht hier von 1:1, 1:n oder auch n:m beziehungen, die entsprechend über die jeweiligen tabellen abgebildet werden. so hast du aller wahrschenlichkeit nach zwischen den tabellen bucher & bücherstapel (noch ein tipp, vermeide buchstaben wie ü in objektnamen) eben eine solche n:m beziehnug. ausgesprochen sagt man, ein buch kann in mehrere stapeln sein, ein stapel kann mehrere bücher haben. das macht mich ein wenig stutzig, weil ein buch sollte eigentlich nicht in verschiedenen stapeln auftauchen, aber das hängt stark davon ab, was genau du damit abbildest. muss man noch mal schauen.

      Das hängt auch davon ab, ob "Buch" als Entität oder als Klasse definiert wird. Gibt es von der Klasse "Buch" mehrere Exemplare, können die sehr wohl in mehreren Stapeln vorkommen. Dann fehlt nur noch eine Tabelle, die die Entitäten beschreibt.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. moin Tom,

        Das hängt auch davon ab, ob "Buch" als Entität oder als Klasse definiert wird. Gibt es von der Klasse "Buch" mehrere Exemplare, können die sehr wohl in mehreren Stapeln vorkommen. Dann fehlt nur noch eine Tabelle, die die Entitäten beschreibt.

        das hängt sicherlich auch davon ab ja, deswegen sollte man auch immer nachfragen. aber ich würde es weniger entität oder klasse bennen, in rdbms spricht man dann doch eher von entitätstypen und entitäten.

        Ilja

    2. SELECT COUNT(*)
      FROM bucher b
      WHERE b.jgst = hier_ein_bestimmer_wert
      AND NOT EXISTS (SELECT NULL
                      FROM buch_in_stapel bis
                      WHERE bis.buchid b.id
                      AND stapelid = 1
                     )
      ;

      Perfekt! Auf die Idee mit den Unterabfrage bin ich gar nicht gekommen, da ich das bislang noch nicht gebraucht habe. Ich habe alles mit Joins gemacht. Und da meine Datenmenge recht klein sind, ist das auch kein Performance-Problem eigentlich gewesen.

      Ich habe aber noch mal meine Problem genauer beschrieben, vielleicht lässt sich ja eine bessere Struktur entwickeln.

      jüla

  4. Tabelle bucher mit id, titel, jgst
    Tabelle bücherstapel mit id, jgst, name
    Tabelle buch_in_stapel mit id, buchid, stapelid

    Das ganze soll eine Schulbücher-Abfrage ergeben. Die Bücher werden ua. mit titel und Jahrgangsstufe (jgst) verwaltet.

    Jeder Schüler bekommt dann später einen Bücherstapel (stapel->stack) zugordnet, wobei ein Stapel aus mehreren Büchern besteht und jedes Buch in mehreren Stapeln vorkommen kann.

    Im Grunde geht es mir darum, dass ich eine Oberfläche habe bei der ich diese Stapel zusammenstellen kann. Ich habe also zB im linken Bereich den vorher ausgewählten Bücherstapel mit seinen Büchern. Und im rechten Bereich des Fensters alle Bücher die in den Stapel aufgenommen werden könnten, wobei das ja nur die aus der gleichen Jahrgangstufe sind. Und die Bücher, die bereits im Stapel sind, dürfen im rechten Bereich ja nicht noch einmal angezeigt werden.

    Ich wollte jetzt zunächst beide Listen durch zwei Abfragen aufbauen, aber nachdem das wohl irgendwie nicht wirklich gut zu machen ist, muss ich das vielleicht irgendwie per php auseinander sortieren. Oder habt ihr noch eine Idee?

    jüla

    1. Hello,

      Jeder Schüler bekommt dann später einen Bücherstapel (stapel->stack) zugordnet, wobei ein Stapel aus mehreren Büchern besteht und jedes Buch in mehreren Stapeln vorkommen kann.

      Nicht die Entität "Buch" kann in mehreren Stapeln vorkommen, sondern nur die Klasse "Buchtitel".
      Du benötigst also erst eine ordentliche Abbildung der Wirklichkeit auf die Mikrowelt der Datenbank.

      Tabellen

      • Buchtitel

      • Jahrgangsstufenmaterial  (2010, 10, Buchtitel_01) (2010, 10, Buchtitel_02)

      • Jahrgangsstufe           (2010, 10), (2010, 11), (2010, 12), ...

      • Schueler

      • Schuelerentwicklung      (ID, Schueler-ID, 2010, 10)

      • Buch                     (id, Buchtitel, angeschafft, ...)

      Jeder Schüler gehört jedes Jahr genau einer Jahrgangsstufe an, im Laufe der Jahre aber unterschiedlichen
      Jedes Buch kann nur bei genau einem Schueler sein
      Von jedem Buchtitel kann es mehrere geben, die jedes Jahr bei einem anderen Schüler sind

      usw.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Nicht die Entität "Buch" kann in mehreren Stapeln vorkommen, sondern nur die Klasse "Buchtitel".

        Mmmh, diese Unterscheidung verstehe ich nicht ganz. Wieso die Unterscheidung zwischen Buch und Buchtitel. Buchtitel ist doch ein Attribut eines Buches.

        • Buchtitel

        Also nur den Buchtitel und eine id?

        • Jahrgangsstufenmaterial  (2010, 10, Buchtitel_01) (2010, 10, Buchtitel_02)

        Das würde dann ja wohl einem Buchstapel entsprechen, oder? Jahrgang, Jahrgangstufe und das Buch. Richtig?

        • Jahrgangsstufe           (2010, 10), (2010, 11), (2010, 12), ...
        • Schueler
        • Schuelerentwicklung      (ID, Schueler-ID, 2010, 10)
        • Buch                     (id, Buchtitel, angeschafft, ...)

        Hier ist doch auch wieder der Buchtitel drin?

        Jedes Buch kann nur bei genau einem Schueler sein

        Es soll nicht zwischen den einzelnen Bücher unterschieden werden. Die Bücher sollen nicht per Code eindeutig identifiziert werden. So dass es keine 1:1 Beziehung zwischen Buch und Schüler gibt.

        Problematisch ist bei mir momentan noch, wie ich bei meiner Aufteilung noch herausfinden soll, wie viele Bücher vergeben sind.

        Ah, ich glaube, dass du mit Buchtitel ein einzlnes Exemplar meinst. Wie gesagt, dass soll gar nicht berücksichtigt werden.

        Viele Grüße,

        jüla

        1. 'ǝɯɐu$ ıɥ

          Mmmh, diese Unterscheidung verstehe ich nicht ganz. Wieso die Unterscheidung zwischen Buch und Buchtitel. Buchtitel ist doch ein Attribut eines Buches.

          Das hinkt jetzt: Es mag tausende Bücher äh Menschen mit dem Titel äh Namen Jüla geben aber dich gibt es nur einmal. Dein Freund könnte also tausende Freundinnen namens Jüla haben, dich aber nur einmal.

          ssnɹƃ
          ʍopɐɥs

          --
          I like children. If they're properly cooked.
          - W.C. Fields
        2. Hello,

          Nicht die Entität "Buch" kann in mehreren Stapeln vorkommen, sondern nur die Klasse "Buchtitel".

          Mmmh, diese Unterscheidung verstehe ich nicht ganz. Wieso die Unterscheidung zwischen Buch und Buchtitel. Buchtitel ist doch ein Attribut eines Buches.

          Jein.
          Man ungterscheidet hier zwischen Stammdaten und Bewegungsdaten und in Deinem Fall sind die mMn auch getrennt voneinander zu führen.

          In den Stammdaten "Buchtitel" wird das Buch in seinen allgemeinen Daten beschrieben. Es muss aber noch keines davon physisch vorhanden sein.

          In der Tabelle "Buch" werden dann die tatsächlich vohandenen Buchexemplare geführt. Dort sollten aber auch nur einwertige, nicht veränderliche Attribute auftauchen, also z.B. Anschaffungsdatum, ID-Lieferant, Einkaufspreis, Standard-Standort, ausleihbar, usw.

          Veränderliche Attribute, wie z.B. der Zustand, an wen es gerade ausgeliehen ist, usw. sollten wieder in jeweils eigenen Tabellen geführt werden.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
      2. Hi,

        Jedes Buch kann nur bei genau einem Schueler sein

        Sag sowas nicht. Bücher kann man zerreißen ...

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        O o ostern ...
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
        1. Hello,

          Jedes Buch kann nur bei genau einem Schueler sein

          Sag sowas nicht. Bücher kann man zerreißen ...

          Ach ja, das habe _ich_ jetzt übersehen. Man kann eben nie an alles denken :-)

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de