Archiv verlassen und diese Seite im Standarddesign anzeigen : mysql reihenfolge tauschen?
Hallo liebe leute!
Ich sags gleich ich bin ein riesen php&mysql noobi und bin da grad am selbst einlernen ... :scared:
Bin aber grad auf ein Problem gestossen!
Hab folgende Tabelle im mysql:
ID | name | text | sort_id
1 | Klaus | Text | 1
2 | Nina | Text | 2
4 | Benni | Text | 4
5 | Martina | Text | 5
Der Eintrag 3 wurde gelöscht...
Jetzt möchte ich zb.: mit Up/Down Buttons die reihenfolge ändern... nur: :dnuhr:
Danke schonmal wieder im voraus :)
Es ist zwar so, dass MySql eine Reihenfolge in Spalten und Zeilen hat, aber die spielt im Prinzip keine Rolle und es ist schlechter Stil, sich darauf zu verlassen, ohne dass man "order" Anweisungen (für Zeilen) spezifiziert.
Wieso willst du die Reihenfolge in der Datenbank ändern? Relationale Datenbanken sehen konzeptionell keine Ordnung für Zeilen und Spalten vor.
Wenn du die Reihenfolge für die Anzeige auf einer Webseite ändern willst, dann könntest du die Spalte sort_id dazu verwenden, die mir dem Namen nach eh dafür vorgesehen scheint.
Das ganze wird als news nacheinander ausgegeben.. da möchte im backend schon die reihenfolge änderbar machen...
Wenn etwas gelöscht wird dann müsstest du einfach bei allen weiteren Einträgen sort_id um eins runterzählen. Also quasi so:
$sort_id ist in PHP die Sortierungsreihenfolge des zu löschenden Eintrags (musst du vorher ggf. aus der Datenbank holen), der Rest sollte dann mit einem MySQL-Query zu machen sein:
"UPDATE tabelle SET sort_id = sort_id - 1 WHERE sort_id > $sort_id"
Wenn etwas gelöscht wird dann müsstest du einfach bei allen weiteren Einträgen sort_id um eins runterzählen. Also quasi so:
$sort_id ist in PHP die Sortierungsreihenfolge des zu löschenden Eintrags (musst du vorher ggf. aus der Datenbank holen), der Rest sollte dann mit einem MySQL-Query zu machen sein:
"UPDATE tabelle SET sort_id = sort_id - 1 WHERE sort_id > $sort_id"
Das würd mal ein Problem lösen :)
Der rest dann?
$posAlt = mysql_fetch_assoc(mysql_query('SELECT `sort_id ` FROM `tabelle` WHERE `sort_id` = $id');');
$posNeu = $posAlt['sort_id']+1;
if ($posNeu > $posAlt) {
mysql_query('UPDATE `tabelle` SET `sort_id` = `sort_id`-1 WHERE `sort_id` BETWEEN $posNeu AND $posAlt');
} else {
mysql_query('UPDATE `tabelle` SET `sort_id` = `sort_id`+1 WHERE `sort_id` BETWEEN $posAlt AND $posNeu');
}
mysql_query('UPDATE `tabelle` SET `sort_id` = $posNeu WHERE `sort_id` = $id');
$id = Die ID des zu verschiebenden...
Boah mein Hirn hat sich gerade geröstet ^^
Was genau bezweckst du damit? Ich werd nicht so recht schlau daraus, außerdem scheinen ein paar Fehler drin zu sein :D
Hmmm der Sinn der Sache im hoffentlich verständlichen:
Frontend:
News 4
News 3
News 2
News 1
Älteste News oben also News 4
Jetzt ändert sich zB. ein Datumseintrag im News 4 und findet Beispielsweise früher statt als News 3. Und die News 1 kommen dieses Jahr wieder also Datum ändern und als erstes ausgeben.
Folglich gehört die Reihenfolge dann so:
News 1
News 3
News 4
News 2
Ich könnte jetzt im Backend natürlich auch ein Textfeld machen mit Reihenfolge Nummer, aber für die einfachheit möchte ich gerne News nach oben Button und News nach unten Button :)
Hoffentlich könnt ihr euch jetzt da was vorstellen :)
Warum sortierst du die News nicht einfach nach Datum???
Das ganze wird als news nacheinander ausgegeben.. da möchte im backend schon die reihenfolge änderbar machen...
Das macht man nicht so, sondern im Idealfall so:
Warum sortierst du die News nicht einfach nach Datum???
Da deine Tabelle nun aber schon ohne Datum spezifiziert ist, müsstest du das entweder nachträglich ändern, oder lässt dir die News sortiert nach Primärschlüssel ausgeben, dann stimmt auch die Reihenfolge mit der Erstell-Reihenfolge überein.
Etwa:
SELECT * from tabelle ORDER BY id DESC LIMIT 5Damit holst du die ersten 5 Zeilen (LIMIT 5) aus der Tabelle, wobei die Zeilen nach der id absteigend (DESC) sortiert (ORDER BY) werden. Da die id eigentlich ein automatisch inkrementierter Wert sein sollte, handelt es sich dabei um die neusten 5 News.
Wenn du nun die News mit den Ids 1 bis 10 hast und die mit id 9 löschst, dann musst du nichts verschieben, das Ergebnis ist immernoch das selbe: Die neusten 5 News.
Du brauchst keine sort-id, das alles wird dir geschenkt. Einmal relativ durch die ids, auch wenn da Lücken drin sein sollten und wenn du ein Datum hinzunimmst sogar absolut.
SQL ist eine sehr mächtige Abfragesprache, man kann etliche Vorbearbeitung direkt über die Abfragen erledigen, statt sie mühselig in Php zu bearbeiten. :)
Tja das wär bestimmt die einfachere lösung... aber nicht die bequemere im endeffekt..
Ist ja so ein kleines CMS was kollege mal gebaut hat, aber alles sehr... kompliziert ist, darum überarbeite ich das ganze :)
die Tabelle um die es sich eigentlich handelt ist folgende:
Tabelle: "news"
ID | bezeichnung | htmlcode | sort_id
-------------------------------------------
1 | faschings... | <h1 fas... | 1
2 | hochseilg... | <h2 tel... | 2
.
.
.
Der ganze htmlcode wir so zu sagen in DB gespeichert und von dort am frontend wieder richtig ausgegeben...
Die alter version dieses cms ist bei einigen kunden noch drauf... die beschweren sich das es kompliziert ist etc... darum muss ich das zeuchs umschreiben... leider bin ich noch im mysql lernen :)
Fragen zu SQL könnte ich im benötigten Umfang vermutlich weitesgehendst beantworten, du kannst also gerne welche stellen.
EDIT: Kermit bringt auf den Punkt, was ich oben sagen wollte.
Die Sortierung muss doch gar nicht fortlaufend sein. 1235 ist die selbe reihenfolge wie 1234. Ob da jetzt eine Zahl zwischendrin fehlt oder nicht, ist bei der Ausgabe egal.
Die Sortierung muss doch gar nicht fortlaufend sein. 1235 ist die selbe reihenfolge wie 1234. Ob da jetzt eine Zahl zwischendrin fehlt oder nicht, ist bei der Ausgabe egal.
Das ist mir ja auch egal :)
die order_id oder die ID werden ja nicht wieder mit ausgegeben daher spielt das keine rolle..
Was ich eigentlich damit sagen will:
Ein User möchte im backend den eintrag 2.News als erstes ausgeben, aus welchen grund auch immer, klickt er daneben das pfeilup icon ---> sql soll dann 2.News sort_id ne 1 geben und 1.News dann praktisch darunter setzen... also sort_id 2
Das sollte dann mit allen Newseinträgen egal wieviele funzen... auch umgekehrt also zB. 5.News nach unten und dafür dann 6.News nach oben wechseln
allerdings übergebe ich nur mit den up/down icons die momentane ID ($posAlt)
Also:
muss ich von der ID die ich bekomme ($posAlt) die nächs höhere bzw. die niedrigere ID finden ($posNeu) und die beiden IDs einfach tauschen...
Wie stell ich das genau an mit mysql befehlen?^^
$posAlt = mysql_fetch_assoc(mysql_query('SELECT `sort_id` FROM `tabelle` WHERE `ID` = '.(int)$id));
$posNeu = $posAlt['sort_id'] + 1;
Du solltest bei dem Link am besten noch einen "direction"-Parameter hinzufügen, dann setzt du bei posNeu einfach je nachdem ein + oder ein -. Da die Datensätze eigentlich konsistent sein sollten, wenn niemand händisch darin herumpfuscht, müsste das im Normalfall funktionieren.
Im nächsten Schritt updatest du jetzt einfach die beiden Einträge mit der jeweils zugehörigen Position.
Danke nochmal für die schnelle hilfe hier :)
Also ich geb jetzt über den icons nichmehr ID mit sondern die order_id(sort_id)
if(!empty($_GET['up']) or !empty($_GET['down']))
{
if(!empty($_GET['up'])){$altPos = $_GET['up']; $upordown = ">";}
else if(!empty($_GET['down'])) {$altPos = $_GET['down']; $upordown = "<";}
$sqlnew = mysql_query('SELECT order_id FROM `news` WHERE order_id '.$upordown.' '. $altPos.' LIMIT 1');
$neuPos = mysql_fetch_row($sqlnew);
$neuPos = $neuPos[0];
echo("Ausgabe: ". $neuPos . "<br />");
}
Soweit sollte er jetzt immer die darüber oder darunterliegende reihe als $neuPos auswählen, richtig?
PS.: Ist das programmiertechnisch gesehen leserlich und einfach geschrieben...?
§wink
Ist nicht getestet, müsste aber eigentlich funktionieren.
Statt up / down als Parameter zu verwenden solltest du dafür einfach einen direction-Parameter verwenden. Hat dieser den Wert 1, dann heißt dass das der aktuelle Eintrag nach unten verschoben wird, ansonsten wir er nach oben verschoben.
Zusätzlich musst du jetzt noch einen Parameter mit der sort_id des aktuellen Eintrag übergeben, ich habe id benutzt.
Zum PS.: Nein :p Du solltest bei if-else-Abfragen und auch sonst immer eine übersichtliche Einrückung vornehmen, sodass man sofort sieht was wozu gehört...
Edit: Ich merk gerade, MySQL kommt mit dem + / - nicht zurecht, ich werd das nochmal kurz überarbeiten. Die richtige Version befindet sich im nächsten Beitrag.
So ists richtig:
if(!empty($_GET['direction']) {
$altPos = (int) $_GET['id']; //sort_id vom aktuellen eintrag
$neuPos = $_GET['direction'] == 1 ? $altPos + 1 : $altPos - 1;
$sqlnew = mysql_query('UPDATE `news` SET order_id = '.$neuPos.' WHERE `sort_id` = '.$altPos.';
UPDATE `news` SET order_id = '.$altPos.' WHERE `sort_id` = '.$neuPos);
}
So ists richtig:
if(!empty($_GET['direction']) {
$altPos = (int) $_GET['id']; //sort_id vom aktuellen eintrag
$neuPos = $_GET['direction'] == 1 ? $altPos + 1 : $altPos - 1;
$sqlnew = mysql_query('UPDATE `news` SET order_id = '.$neuPos.' WHERE `sort_id` = '.$altPos.';
UPDATE `news` SET order_id = '.$altPos.' WHERE `sort_id` = '.$neuPos);
}
Aber das + und - wird nicht für lücken funktionieren?^^
Edit: den up down parameter brauch ich ja weil je nach icon(up oder down) was geklickt wird sich die reihenfolge ändern soll....?
Dafür ist ja das $direction da. Ist $direction == 1, dann wird der aktuelle Eintrag nach unten verschoben und ist er irgendwas anderes dann nach oben.
Für Lücken funktioniert das nicht - stimmt. Allerdings sollte sort_id konsistent sein, solange du alle Einträge mit deinem Admin-Panel und nicht etwa bei phpMyAdmin bearbeitest.
Dafür ist ja das $direction da. Ist $direction == 1, dann wird der aktuelle Eintrag nach unten verschoben und ist er irgendwas anderes dann nach oben.
Für Lücken funktioniert das nicht - stimmt. Allerdings sollte sort_id konsistent sein, solange du alle Einträge mit deinem Admin-Panel und nicht etwa bei phpMyAdmin bearbeitest.
Man sollte die news auch löschen können.. :( ... lücken
das hab ich aber schon eingebaut
Edit:
SELECT order_id FROM `news` WHERE order_id > 1 ORDER BY order_id ASC LIMIT 1;
SELECT order_id FROM `news` WHERE order_id <4 ORDER BY order_id DESC LIMIT 1
Das müsst doch immer den nächsten in Liste ausgeben so weit ich das sehe?
Nochmal Edit:
Das klappt mit auswahl :)
Aber! Die alles Entscheidende Frage: Wie wechsel ich jetzt die beiden reihen per mySQL aus? ^^
Hab schon massig rumprobiert aber irgendwie will er nicht :(
Ich steig langsam nichtmehr durch, Außerdem hast du einmal eine neue Zeile namens order_id, was ist das schon wieder? :D
Für den Fall des Löschens schau mal in meine erste Antwort. §wink
order_id = sort_id !^^ Hab nur anfangs nicht genau gewusst wie ich es benannt hatte :eek:
Das mit löschen is ja mit dem egal:
SELECT order_id FROM `news` WHERE order_id > 1 ORDER BY order_id ASC LIMIT 1;
SELECT order_id FROM `news` WHERE order_id <4 ORDER BY order_id DESC LIMIT 1
Da er hiermit die nächst höhere oder niedrigere order_id sucht.
Hab jetzt beide ids:
- Einmal die order_id die nen neuen platz bekommt
- Und die order_id die den platz mit der anderen tauscht
Aber wie lautet der mysql syntax zum tauschen?
$savePos = 0; //order_id where to temporary save
// Save neuPos to savePos
mysql_query('UPDATE `news` SET `order_id` = '.$neuPos.' WHERE `order_id` ='.$savePos.';');
// Set altPos to neuPos
mysql_query('UPDATE `news` SET `order_id` = '.$altPos.' WHERE `order_id` ='.$neuPos.';');
// Set savePos to altPos
mysql_query('UPDATE `news` SET `order_id` = '.$savePos.' WHERE `order_id` ='.$altPos.';');
Hab das versucht... bin aber damit gescheitert :dnuhr:
Blue Force
22.04.2010, 22:12
$savePos = 0; //order_id where to temporary save
// Save neuPos to savePos
mysql_query('UPDATE `news` SET `order_id` = '.$neuPos.' WHERE `order_id` ='.$savePos.';');
// Set altPos to neuPos
mysql_query('UPDATE `news` SET `order_id` = '.$altPos.' WHERE `order_id` ='.$neuPos.';');
// Set savePos to altPos
mysql_query('UPDATE `news` SET `order_id` = '.$savePos.' WHERE `order_id` ='.$altPos.';');
Hab das versucht... bin aber damit gescheitert :dnuhr:
Ich denke das Problem war dass du nach der ersten Query 2x neupos als sort_id in der Liste hast. dann gehts nicht mehr eindeutig weiter.
Vielleicht gehts so:
$savePos = 0; //order_id where to temporary save
// Save neuPos to savePos
mysql_query('UPDATE `news` SET `order_id` = '.$savePos.' WHERE `order_id` ='.$neuPos.';');
// Set altPos to neuPos
mysql_query('UPDATE `news` SET `order_id` = '.$neuPos.' WHERE `order_id` ='.$altPos.';');
// Set savePos to altPos
mysql_query('UPDATE `news` SET `order_id` = '.$altPos.' WHERE `order_id` ='.$savePos.';');
Ich denke das Problem war dass du nach der ersten Query 2x neupos als sort_id in der Liste hast. dann gehts nicht mehr eindeutig weiter.
Vielleicht gehts so:
$savePos = 0; //order_id where to temporary save
// Save neuPos to savePos
mysql_query('UPDATE `news` SET `order_id` = '.$savePos.' WHERE `order_id` ='.$neuPos.';');
// Set altPos to neuPos
mysql_query('UPDATE `news` SET `order_id` = '.$neuPos.' WHERE `order_id` ='.$altPos.';');
// Set savePos to altPos
mysql_query('UPDATE `news` SET `order_id` = '.$altPos.' WHERE `order_id` ='.$savePos.';');
Es funzt! :)
Danke das ihr eure Zeit für mich bergeudet habt :gratz
Eine Frage noch: Brauche ich die SavePosition als Zwischenspeicher überhaupt?
...ich sollte wirklich paar mysql tutorials abarbeiten:D
Powered by vBulletin® Version 4.2.2 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.