Data: Mysql Abfrage - stehe gerade auf dem Schlauch

Hallo
arbeite mit
PHP 5.2.6 & MySql 5.0.67
und stehe gerade bei einer Abfrage auf dem Schlauch
Bastle mir gerade eine Vokabelabfrage und habe eine Tabelle Vokabeln und eine Tabelle Kasten
Wenn ich Vokabel richtig habe kommt sie in den Kasten - soweit so klar und wenn ich die einzelnen Kästen bearbeite wird die Zuordnung Kasten hoch bzw. runter gezählt auch kein Problem, allerdings wenn ich neue Vokabeln aktivieren möchte muss ich überprüfen ob dieses Wort schon in der Tabelle Kasten vorkommt...
Tabelle Vokabel (vereinfacht):
vo_id, deutsch, uebersetzt, sprache_id
Tabelle Kasten
ka_id, vo_id, kasten_nr_d, kasten_nr_ue, user_id, versuche

Jetzt will ich ein beliebiges neues Wort in die Lernphase übernehmen:
Select vo_id, dt, uebersetzt, from vokabel where sprache_id='$sp_id' ORDER BY rand() LIMIT 1
OK, ich bekomme ein beliebiges Wort, allerdings kann es sein, dass es schon in der Lernphase drin ist.
Wie kann ich die Abfrage so schreiben, dass mir nur Wörter ausgegeben werden, die der jeweilige User noch nicht bearbeitet hat und die damit nicht in der Tabelle Kasten vorhanden sind (eigentlich müßte man das ogar noch ausweiten und schauen in welcher Reihenfolge gearde gelernt wird Deutsch-Fremdsprache oder Fremdsprache-Deutsch - das ist über kasten_nr_d bzw kasten_nr_ue festgehalten eine Vokabel kann also z.B. 0 in kasten_nr_d haben und 3 in kasten_nr_ue)?

Hoffe ich habe mich einigermaßen verständlich ausgedrückt.

Wäre klasse wenn ihr mir weiterhelfen könntet

  1. Tach!

    Wie kann ich die Abfrage so schreiben, dass mir nur Wörter ausgegeben werden, die der jeweilige User noch nicht bearbeitet hat und die damit nicht in der Tabelle Kasten vorhanden sind [...]?

    Eine Methode nutzt einen Left Join von Vokabel nach Kasten. Für das was im Kasten nicht enthalten ist, sind die Kasten-Felder (z.B. die Id) NULL. Darauf kann man testen. Eine andere Methode ist eine Subquery mit NOT EXISTS.

    dedlfix.

    1. Eine Methode nutzt einen Left Join von Vokabel nach Kasten. Für das was im Kasten nicht enthalten ist, sind die Kasten-Felder (z.B. die Id) NULL. Darauf kann man testen. Eine andere Methode ist eine Subquery mit NOT EXISTS.

      dedlfix.

      Hi dedlfix,
      danke schonmal für die Antwort.
      Wie das mit dem Leftjoin laufen soll ist mir nicht ganz klar - wie kann ich so auf nicht vorhandene IDs bzw. NULL in den Kasten-Feldern auswählen??

      Mit dem Subquery wie soll das dann aussehen? Ungefähr so:

      SELECT DISTINCT vo_id FROM vokabel
        WHERE NOT EXISTS (SELECT * FROM kasten
                          WHERE kasten.vo_id = vokabel.vo_id) and sprache_id='$sp_id';

      Wenn das so richtig ist, prüfe ich nur ob die Vokabel überhaupt nicht in der Tabelle Kasten vorhanden ist. Ich prüfe allerdings nicht ob sie nur in einer der beiden Abfrage Reihefolgen (DT/FS FS/DT) vorkommt.
      Ginge das:

      SELECT DISTINCT vo_id FROM vokabel
        WHERE NOT EXISTS (SELECT * FROM kasten
                          WHERE (kasten.vo_id = vokabel.vo_id) OR (kasten_nr_d='0' ) and sprache_id='$sp_id';

      bzw. halt dann für die andere Reihenfolge der entsprechend andere Kasten - wäre so was richtig?
      Kann leider gerade nicht testen, da mein WAMP Server mal wieder abgestürzt ist.

      Grüße
      Data

      1. SELECT DISTINCT vo_id FROM vokabel
          WHERE NOT EXISTS (SELECT * FROM kasten
                            WHERE (kasten.vo_id = vokabel.vo_id) OR (kasten_nr_d='0' ) and sprache_id='$sp_id';

        NEE, sehe gerade das kann nicht funktionieren - da muß ich nochmal drüber schauen - sorry.

      2. Tach!

        Wie das mit dem Leftjoin laufen soll ist mir nicht ganz klar - wie kann ich so auf nicht vorhandene IDs bzw. NULL in den Kasten-Feldern auswählen??

        Ungefähr so: SELECT a.feld FROM a LEFT JOIN b ON a.b_id=b.id WHERE b.id IS NULL

        Wenn das so richtig ist, prüfe ich nur ob die Vokabel überhaupt nicht in der Tabelle Kasten vorhanden ist. Ich prüfe allerdings nicht ob sie nur in einer der beiden Abfrage Reihefolgen (DT/FS FS/DT) vorkommt.

        Die Subquery muss allein ausgeführt für die Vokabel ein Ergebnis bringen, die unter all deine Bedingungen bereits enthalten ist. Dann kannst du sie Query als Subquery einfügen.

        dedlfix.

  2. hi,

    erst mal lob fürs angeben der Versionen!

    mal rein vom Verständnis:
    1. Unbearbeitete Vocabeln haben theoretisch versuche = 0
    2. Vocabeln kommen im ganzen nur einmal vor

    Damit ergibt sich für mich, dass man Vocabel und Kasten als eine Tabelle machen könnte.

    In einer 2. speichert man sich dann "User, Versuch, vocabel_id, gelernt"
    Sobald der user in den einen "kasten" rein geht, werden in der 2. tabelle alle einträge des Kastens vorgenommen. Angezeigt werden dann immer die mit den wenigsten versuchen.

    So muss der User erst durch die vocabeln des einen kastens durch, bevor er sie wieder von vorne bekommt.

    In der Abfrage dann einfach ein Join verwenden, damit du nur die vocabeln eines kastens bekommst.

    Ich glaub das erfüllt so auch irgend eine Normalisierungsstufe, da keine Texte doppelt sind und die 2 tabellen keine redundanz bieten.

    Hoffe ich habe deine Frage damit soweit richtig erfasst.

    Gruß Niklas

    --
    Man muss nicht alles wissen, man sollte aber wissen, wo das nicht gewusste zu finden ist.
      1. Unbearbeitete Vocabeln haben theoretisch versuche = 0
      2. Vocabeln kommen im ganzen nur einmal vor

      Damit ergibt sich für mich, dass man Vocabel und Kasten als eine Tabelle machen könnte.

      Hi Niklas,
      ganz so einfach ist es nicht: das von Dir vorgeschlagene hatte ich schon gemacht, nur für mich und nur für eine Sprache, dann ist das alles kein Problem und man kann sich die eine Tabelle tatsächlich sparen. Allerdings bin ich dummerweise ergeizig geworden und wollte das ganze nun für n-Sprachen und n-Benutzer machen - und dadurch wird alles leider deutlich komplizierter als ich mir das am Anfang gedacht habe. Zur Zeit wären 4 Sprachen und 3 Nutzer am Start - d.h. sobald ich meine kleinen Probleme gelöst habe. :-)

      Grüße
      Data

      1. hi,

        benutzer kannst du jetzte bereits unbegrenzt viele haben, da diese in der struktur berücksichtigt sind.

        Die Sprache kannst du über die Karteikästen zuordnen.

        Somit eine weitere tabelle: "id_kasten, lang_kasten, name_kasten"
        bzw usertabelle noch: "id_user, name, passwort"

        über kasten, vocinkasten, lernplan, users solltest du das gewünschte so hinbekommen, ohne daten doppelt belegen zu müssen.

        Das gemeine dürfte nur sein, dass du bereits das ganze hast und meine idee halt einfach einen anderen Aufbau vorraussetzt. Kenne das problem leider nur zu gut, wenn man danach ergeiziger wird ;)

        man könnte das ganze ja auch noch komplexer planen, dass man nicht nur deutsch als ausgangswort hat, sondern jede sprache zu jeder anderen. dafür wäre meine struktur wiederum nicht ok ...

        Gruß Niklas

        --
        Man muss nicht alles wissen, man sollte aber wissen, wo das nicht gewusste zu finden ist.
        1. man könnte das ganze ja auch noch komplexer planen, dass man nicht nur deutsch als ausgangswort hat, sondern jede sprache zu jeder anderen. dafür wäre meine struktur wiederum nicht ok ...

          Ja das hatte ich mir auch schon überlegt - very sophisticated!
          Mmmh, vielleicht sollte ich das bisherige über den Haufen schmeissen und noch mal ganz von vorne anfangen und dann gleich diese Option mit einbauen. Trotzdem würde ich gerne lernen wie ich mein Ausgangsproblem löse (ähnliche Probleme ergeben sich ja immer wieder mal).

          Grüße
          Data

          1. hi,

            guter Ansatz, das Problem lösen und nicht nur umgehen zu wollen.
            Ich denke da schau am besten in dedlfix seinen Antworten =)
            Ist hier aber ein tolles Beispiel für Probleme in wachsenden Projekten.
            (oder um es gemeiner auszudrücken: Beispiel für zu wenig Planung)

            Viel Glück bei deinem Script!
            Kleiner Tipp noch, gute vocabel Programme sortieren die vocabeln immer per random, damit man nicht die reihenfolge lernt!

            Gruß Niklas

            --
            Man muss nicht alles wissen, man sollte aber wissen, wo das nicht gewusste zu finden ist.
  3. Tach!

    Warum schreibst du überhaupt das trölfmillionste Vokabel-Lernprogramm, noch dazu nach der sattsam bekannten Kasten-Methode? Willst du dich etwa nur vor dem Lernen drücken?

    dedlfix.

    1. Tach!

      Warum schreibst du überhaupt das trölfmillionste Vokabel-Lernprogramm, noch dazu nach der sattsam bekannten Kasten-Methode? Willst du dich etwa nur vor dem Lernen drücken?

      dedlfix.

      Wollte halt mal schauen ob ich das hinbekomme - Übung macht den Meister - und dann habe ich mir da noch ein paar Features eingebaut die ich so bisher noch nicht gesehen habe (habe mich aber ehrlich gesagt auch noch nicht groß nach anderen Programmen umgeschaut)!
      Kennst Du ein bessere Methode als die Kasten-Methode (dankbar für jeden Hinweis)?

      Grüße
      Data

      1. Tach!

        Kennst Du ein bessere Methode als die Kasten-Methode (dankbar für jeden Hinweis)?

        Such dir einen Tandem-Partner. Wörter, Redewendungen und Grammatik, die man grad braucht, lernen sich einfacher als Vokabeln ohne Bezug einen Bezug zu dir oder deinem Tun. Allerdings braucht es dann eine gemeinsame Sprache zum Verständigen.

        dedlfix.

        1. hi,

          Tach!

          Kennst Du ein bessere Methode als die Kasten-Methode (dankbar für jeden Hinweis)?

          Such dir einen Tandem-Partner. Wörter, Redewendungen und Grammatik, die man grad braucht, lernen sich einfacher als Vokabeln ohne Bezug einen Bezug zu dir oder deinem Tun. Allerdings braucht es dann eine gemeinsame Sprache zum Verständigen.

          »»

          Oder ein Jahr im Ausland ;)
          Von meiner Englisch Lehrerin hab ich folgendes:
          Immer im ganzen Satz lernen. Gleichbedeutendes bzw. gegenteile lernen.

          Gruß Niklas

          --
          Man muss nicht alles wissen, man sollte aber wissen, wo das nicht gewusste zu finden ist.