kostenloser Webspace werbefrei: lima-city


MySQL Rechnen mit if Abfrage

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    quest

    quest hat kostenlosen Webspace.

    Hi Leute,

    ich versuche gerade eine MySQL Abfrage zuschreiben, bei der die Einträge nach einer gewissen Zeit erst wieder ausgelesen werden sollen! Jeder Benutzer soll dabei seine eigene Zeiteinstellung haben. Ich habe derzeit folgenden Code:

    $inhalt=mysql_query("SELECT ID FROM tabelle
      WHERE lup_".$_SESSION['user_id']." +
        (
        IF(kart_".$_SESSION['user_id']."=0,60*60*24,
          IF(kart_".$_SESSION['user_id']."=1,60*60*24*2,
            IF(kart_".$_SESSION['user_id']."=2,60*60*24*4,
              IF(kart_".$_SESSION['user_id']."=3,60*60*24*7,
                IF(kart_".$_SESSION['user_id']."=4,60*60*24*31,60*60*24*365)    
              )  
            )    
          )  
        )<'".time()."' ORDER BY RAND() LIMIT 150")or die("Fehler in Zeile ".__LINE__.": ".mysql_error());


    Das ganze soll später funktionieren wie eine Lernkartei. Wenn die Frage richtig beantwortet wurde kommt die "Karte" einen Stapel nachhinten. In welchem Stapel sich die Karte befindet wird in kart_x gespeichert. In lup_x wird der letzte Aufruf gespeichert werden.

    Leider bekomme ich bei dieser Abfrage folgenden Fehler

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER BY RAND() LIMIT 150' at line 12
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. c****s

    Also deine Query lautet (unter der Prämisse, dass user_id = 5):
    SELECT ID FROM tabelle WHERE lup_5 + ( IF(kart_5=0,60*60*24, IF(kart_5=1,60*60*24*2, IF(kart_5=2,60*60*24*4, IF(kart_5=3,60*60*24*7, IF(kart_5=4,60*60*24*31,60*60*24*365) ) ) ) )<'1254382726' ORDER BY RAND() LIMIT 150

    Das liest sich schon sehr strange. Ein paar Details werfen bei mir den Verdacht auf, das bei deinem relationalem Modell einige Dinge im Argen liegen:
    - Deine Tabelle heißt tabelle.
    - Diese Tabelle hat für jeden Nutzer eine Spalte lup_?. Das ist schon mal gegen das Dogma von RelDB. Der sinnige Ansatz wäre eine Spalte user_id und eine Spalte lup, damit jeder Nutzer seine Zeilen hat und nicht seine Spalten. Du musst sonst ja beim Anlegen und Löschen von Nutzern immer ein ALTER TABLE durchführen.
    - Die IFs im SQL. Ich meine, bei einem sauberen, normierten Datenmodell benötigt man nie IF im SQL, dafür gibt es ja die WHERE-Clause. Zum Beispiel eine Tabelle Zeit mit den Spalten id und value und den Zeilen
    id value
    1  60*60*24*2
    2  60*60*24*4
    3  60*60*24*7
    etc

    Dann würde sich das ganze geiffe nämlich wie folgt lesen
    where 1254382726 - lup_5 > (select value from Zeit where id=kart_5)

    - Warum ist 1254382726 ein Stringliteral und keine Zahl?

  4. Autor dieses Themas

    quest

    quest hat kostenlosen Webspace.

    census schrieb:
    - Deine Tabelle heißt tabelle.


    Die habe ich jetzt mal so genannt, ja.

    - Diese Tabelle hat für jeden Nutzer eine Spalte lup_?. Das ist schon mal gegen das Dogma von RelDB. Der sinnige Ansatz wäre eine Spalte user_id und eine Spalte lup, damit jeder Nutzer seine Zeilen hat und nicht seine Spalten. Du musst sonst ja beim Anlegen und Löschen von Nutzern immer ein ALTER TABLE durchführen.


    Ja hat sie derzeit. Weil ich sonst nicht weiß wie ich einem Datensatz die persönlichen Daten zuordnen kann. Kannst du mir den sagen wie ich das bewerkstellige? Ich will ja für jeden Datensatz in der Tabelle für jeden Nutzer die Einstellungen unterschiedlich speichern. Also wie kann ich in Spalte userid alle ID's speichern und gleichzeitig unterschiedliche Daten des letzten Update's (lup_5) und zusätzlich wann der Datensatz das nächste mal wieder aufgerufen werden soll(kart_5)?
  5. c****s

    Gut, ich weiß zwar noch nicht genau, ob das folgende dem entspricht, was du brauchst, aber hier hast du mal ein Minimalmodell für eine Lernkartei:

    Tabelle Card
    id int not null primary key
    content text
    (oder was halt die Karte enthalten soll)

    Tabelle User
    id int not null primary key
    name varchar(100) not null
    login varchar (100) not null
    pw_hash char (32)

    Tabelle Access
    id_card int not null (als foreign key auf Card)
    id_user int not null (als foreign key auf User)
    lastaccessed timestamp
    nextdue timestamp

    Die Tabelle Card enthält alle Karten.
    Die Tabelle User entählt alle Benutzer.
    Die Tablle Access enthält die Information wann welcher Nutzer welche Karte als letztes benutzt hat und wann diese Karte für diesen Nutzer wieder fällig wird.
    Das ganze ist natürlich nur eine Minimalimplementierung um zu zeigen, wie man eine n-m-Relation realisiert.

    Wenn du zum Beispiel pro Nutzer auch Schubkästen haben willst, durch die die Karten durchrotieren, könnte man das so lösen

    Tabelle Drawer
    id int primary key not null
    owner int not null (als foreign key auf User)
    z-index int (der wievielte Schuber von vorne ist es)

    Tabelle Drawercontent
    id_drawer int not null (als foreign key auf Drawer)
    id_card int not null (als foreign key auf Card)

    Wieder mit n-m-Relation zwischen Schuber und Karte. Jeder Schuber hat n-Karten und jede Karte liegt in n-Schubern (z.B. in meinem Schuber 1 und deinem Schuber 3).

    Ich hoffe ich konnte helfen.
  6. Autor dieses Themas

    quest

    quest hat kostenlosen Webspace.

    OK, das hört sich erst mal sehr gut an!

    Leider stoße ich bei der Umsetzung etwas an meine Grenzen! Wie kann ich PHPMyAdmin denn jetzt sagen das ich "den foreign key" auf Card oder User setzten will???

    Ist es richtig das lastaccessed automatisch auf "ON UPDATE CURRENT TIMESTAMP" gesetzt wird?
  7. c****s

    Das Problem ist, das Limacity aus irgendwelchen Gründen nur MyISAM als Datenbankengine zulässt und somit 90% der Fähigkeiten einer relationalen Datenbank fehlen. Du kannst der Datenbank also nicht mitteilen, dass die Spalten ein Fremdschlüssel ist. Das heißt, es gibt auch keine Kaskadierung beim Löschen oder Aktualisieren und keine Konsistenzprüfung. Darum musst du dich hier per Fuß zu Hand kümmern.
    Das "als foreign key" in meinem Vorposting war auch eher als Info an dich genannt, dass in diesem Feld der Primärschlüssel der anderen Tabelle steht. Musst halt nur aufpassen, dass wenn du eine Zeile löscht, auch alle Referenzen darauf löschen musst. Jede aktuelle DB-Engine (z.B. InnoDB) würde das automatisch machen, wenn du ihm das sagst.
  8. Autor dieses Themas

    quest

    quest hat kostenlosen Webspace.

    Ähhh ja.

    Wie muss den jetzt meine Query in PHP aussehen damit mir die Datenbank die richtigen Daten ausspuckt??? Ich guck garnicht mehr durch!?!?!?
  9. c****s

    Kommt darauf an was du willst. Hier als Beispiel eine Query, die den Inhalt aller Karten liefert, die im Schubkasten Nummer 3 des Nutzers mit dem Namen "census" liegen:

    select content from card join drawercontent on drawercontent.id_card=card.id join drawer on drawcontent.id_drawer=drawer.id join user on drawer.owner=user.id where drawer.z-index=3 and user.login='census';
  10. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!