MySQL Rechnen mit if Abfrage
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abfrage
beispiel
card
code
datenbank
datensatz
dogma
karte
limit
login
not
null
nutzer
ordern
rand
spalte
spalten
syntax
tabelle
zeile
-
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 -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
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 lesenwhere 1254382726 - lup_5 > (select value from Zeit where id=kart_5)
- Warum ist 1254382726 ein Stringliteral und keine Zahl?
-
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)? -
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. -
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? -
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. -
Ähhh ja.
Wie muss den jetzt meine Query in PHP aussehen damit mir die Datenbank die richtigen Daten ausspuckt??? Ich guck garnicht mehr durch!?!?!? -
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';
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage