PHP [MySQL] Vorherigen und Nachfolgenden Datensatz auswählen

raven16

Lieutenant
Registriert
Nov. 2008
Beiträge
580
Hi hab mal ne Frage.

Ich suche aus meiner Datenbank in einer Tabelle eine Zeile raus, die dann auf meiner Webseite angezeigt wird. Unter der Anzeige sollen dann 2 Links positioniert werden, wo man dann den vorherigen und den nachfolgenden Datensatz auswählen kann.
Da kann man sich ja sagen hmmm ist ja einfach, man geht über den Primary Key namens ID und addiert zu dem aktuellen datensatz 1 dazu oder zieht 1 ab...

nur das problem ist, dass die spalte probview mit dem Wert 1 oder 0 regelt, ob das problem angezeigt wird oder nicht...
d.h. ich könnte folgende Datensätze haben:

ID TEXT PROBVIEW

1 Text1 1
2 Text2 0
3 Text3 1
4 Text4 1

Wenn der aktuelle Datensatz z.B. die ID 3 hat dann ist der vorherige datensatz der angezeigt werden soll die ID 1 und der nachfolgende datensatz die ID mit der nummer 4

Ich hoffe ihr versteht was ich meine
 
Function, die dir die ID per SQL-Abfrage liefert(rein mit aktueller ID, raus kommt neue):

Also einmal brauchst du, Nachfolger:
select ID from Tabelle where PROBVIEW = 1 and ID > aktueller ID order by ID and rownum = 1

und einmal Vorgänger:
select ID from Tabelle where PROBVIEW = 1 and ID < aktueller ID order by ID desc and rownum = 1


br
SacredSense
 
Hmmm das hört sich gut an aber ich habs auch zu wenig ausführlich erklärt wie ich das realisieren möchte
Ich habe alle Datensätze vorher schon aus der Datenbank mit dieser Abfrage:
PHP:
$sql_get_all_answers = mysql_query("SELECT COUNT(probid) AS probanzahl FROM probleme
								WHERE probview='1' AND probanswername IS NOT NULL
							") or die(mysql_error()." ->Abfrage <b>sql_get_all_answers</b> klappt nicht");
Mit dieser Abfrage realisiere ich eine Liste von Überschriften, die in einem kleinen Feld angezeigt werden.
In einem Großen Feld werden dann die aufgelisteten Überschriften im Gesamten etwas ausführlicher mit dem dazugehörigen Text angezeigt.

Wählt man eine dieser Überschriften, so wird diese in dem kleinen Feld markiert und in dem großen Feld einzelnd angezeigt.

In dem großen Feld stehen dann die Links vorheriges und nächstes Problem
klickt man auf vorheriges so soll im kleinen feld das vorherige Problem markiert werden und beim nächsten problem eben das nächste problem

Dies soll den vorteil bieten, dass man im kleinen Feld nicht alle Überschriften auswählen braucht sondern einfach zur nächsten oder vorherigen wechseln kann

In dieser While-Schleife werden im kleinen Feld die Überschriften erzeugt
mit der Abfrage wird dort die Blätterfunktion erzeugt, sodass hier durch eine 2. Abfrage 8 Überschriften pro Seite angezeigt werden...
PHP:
while($obj_get_themen = mysql_fetch_object($sql_get_themen))
{
	$titel = $obj_get_themen->probtitel;
	if(strlen($titel)>45) $dots = '...';
	else $dots = '';
	$titel = substr($titel,0,45);
	$titel_filtered = nl2br($titel.$dots);
	echo'
	<div style="width:353px;height:14px;border-top:1px solid #dedede;padding-left:5px;padding-right:5px;">';
	if($_GET['viewprob']==$obj_get_themen->probid)
	{
		echo'<a class="themen_active" href="statistik/klick.php?viewprob='.$obj_get_themen->probid.'&klick=1&auswahl='.$_GET['auswahl'].'&seite='.$_GET['seite'].'">'.$titel_filtered.'</a>';
	}
	else echo'<a class="themen" href="statistik/klick.php?viewprob='.$obj_get_themen->probid.'&klick=1&auswahl='.$_GET['auswahl'].'&seite='.$_GET['seite'].'">'.$titel_filtered.'</a>';
	echo'
	</div>';
}
Die Links die dort erzeugt werden, sollen direkt die probid des vorherigen und nächsten problem enthalten, d.h. ich muss in der While-Schleife die Links dementsprechend erweitern.

Vllt. kann ich ja den aktuellen Datensatz von mysql_fetch_object nehmen und den um 1 rauf zählen und eins abziehen um mein Ziel zu erreichen
 
sacredsense hat nicht ganz unrecht - du kannst 2 subqueries machen - die geben die nächstkleinere und -größere id zurück.

SELECT
t1.id,
t1.title_de,
(SELECT t2.id FROM `table` AS t2 WHERE t2.id>t1.id ORDER BY t3.id DESC LIMIT 1) AS t2_id,
(SELECT t3.id FROM `table` AS t3 WHERE t3.id<t1.id ORDER BY t3.id DESC LIMIT 1) AS t3_id
FROM
`table` AS t1
WHERE
t1.id=...
 
1. Proview muss 1 sein, nur dann ist der Wert relevant
2. DESC für Nachfolger würde immer den größten Wert liefern und nicht den Nächsten der nach dem aktuellen relevant ist.


überarbeitete Abfrage von schnupp schrieb:
SELECT
t1.id,
t1.title_de,
(SELECT t2.id FROM `table` AS t2 WHERE t2.id > t1.id AND PROBVIEW = 1 ORDER BY t3.id LIMIT 1) AS next_id,
(SELECT t3.id FROM `table` AS t3 WHERE t3.id < t1.id AND PROBVIEW = 1 ORDER BY t3.id DESC LIMIT 1) AS prev_id
FROM
`table` AS t1
WHERE
t1.id=...

Würde auch gehen, kann aber dann auch nur da genutzt werden, per Function wäre das innerhalb des Codes flexibler/wiederverwendbar und kann ja auch innerhalb der Abfrage als Select aufgerufen werden.

Quasi so:
Code:
*SELECT
t1.id,
t1.title_de,
,get_next_id(t1.id) AS next_id,
,get_prev_id(t1.id) AS prev_id
FROM
`table` AS t1
WHERE
t1.id=...


br
SacredSense
 
bei der art der anfrage bin ich tendenziell davon ausgegangen, dass mysql-funktionen vielleicht noch ne spur zu viel know how erfordern. am prinzip der anfrage ändert sich aber so auch nichts.
 
je nach anfrage und größenordnung der datentabellen kann es aber durchaus performanceverluste geben, wenn man mit mysql-functions arbeitet. hab da bei nem projekt auch schon mal nen schritt zurück gemacht und die eine oder andere function durch ein schödes left join ersetzt. die abfrage war halt dann nicht mehr so schön einfach aber die performance deutlich besser.
vielleicht war auch meine version mit function nicht gut geschrieben, aber damals hatte ich - bezogen auf die performance - manche probleme mit functions.
 
Naja kommt, wie du schon sagst, auf die Datenmenge und auf die Komplexität der Abfrage an, ab und zu ist auch mal die Indizierung schuld oder die Statistiken müssen mal aktualisiert werden.
Es gibt viele Sachen die Laufzeiten verursachen können, aber bei der Abfrage in diesem Fall, sollten sich weder die eine noch die Andere Variante gravierend voneinander unterscheiden.

Ich würde per function arbeiten, aber das ist jedem selbst überlassen, ist ja vom Ergebnis her gehüpft wie gesprungen ;)


br
SacredSense
 
Ich würde hier den in raum stellen wollen
ob es nicht besser wäre über nested table zu lösen.
 

Ähnliche Themen

Zurück
Oben