SQL Einfache Ausgabe der letzten x Zeilen

  • Ersteller Ersteller Mr. Snoot
  • Erstellt am Erstellt am
M

Mr. Snoot

Gast
Hio,

ich habe eine stetig wachsende Tabelle (d.h. unbekannte Zeilenanzahl) in einer MySQL-DB, von der ich die letzten x Zeilen ausgeben möchte. Ich brauche die Daten aufsteigend sortiert (ASC), kann also erstmal nicht ORDER BY ... DESC anwenden und dann einfach LIMIT x setzen.

Welche Möglichkeiten gibt es, das möglichst einfach zu bewerkstelligen?

  1. mit einer vorherigen DB-Afrage die Zeilenanzahl ermitteln
  2. die DESC-Ausgabe in eine Array speichern und selbiges später wieder ASC sortieren (oder ggf. mit array_unshift arbeiten)
Letzteres könnte von der Performance etwas flotter sein, da keine zusätzliche DB-Abfrage erfolgt. Wirklich gefallen tun mir aber beide Lösungen nicht, weil ich immer einen zusätzlichen Schritt benötige.


Gibt es tatsächlich keine SQL-Funktion um direkt die letzten x Zeilen zu erhalten?
 
Zuletzt bearbeitet:
Mr. Snoot schrieb:
Ich brauche die Daten aufsteigend sortiert (ASC), kann also erstmal nicht ORDER BY ... DESC anwenden und dann einfach LIMIT x setzen.
Warum nicht? Du musst sie dann doch nur rückwärts durchgehen?

Womit greifst du auf die Datenbank zu? PHP? Java? .NET? In jedem dieser Systeme müsste eine Möglichkeit (auf die eine oder andere Weise) vorhanden sein, und sei es, die Daten erstmal der SQL-Ergebnis-Reihenfolge entsprechend auszulesen und dann rückwärts durchzugehen.

'Ne andere (ungetestete) Möglichkeit wäre vielleicht etwas wie
Code:
SELECT ... ORDER BY ... ASC LIMIT (SELECT count(1) FROM ...) - x - 1, x
 
Zuletzt bearbeitet:
Ich greif mit PHP zu.


Was meinst du mit rückwärts durchgehen?

Angenommen ich habe in meiner DB die Zeile: a, b, c, d, e und möchte die letzten drei und mache das mit DESC, dann bekomme ich ja e, d, c. Wie soll das das dann noch umdrehen?

Deine ungetestete Mögichkeit wäre ja quasi zunächst die Zeilenanzahl zu ermitteln; was ich nicht so toll finde.
 
PHP Beispiel:

Code:
$query = mysql_query("SELECT count(*) AS anzahl FROM `tabelle`");
if($row = mysql_fetch_array($query)) { $anzahl = $row['anzahl']; }

$query = mysql_query("SELECT * FROM `tabelle` LIMIT $anzahl, 2");
[...]
 
@mr. snoot: Naja, wenn du a, b, c, d, e hast und willst c, d, e haben, dann lässt du dir e, d, c ausgeben mit DESC und gehst aber nicht in dieser Reihenfolge in PHP durch, sondern fängst hinten an und siehst c, d, e.

@braumeister: das dürfte so nicht funktionieren. Der erste Parameter für Limit ist das (null-basierte) Offset. Deine zweite Abfrage möchte ab der ersten Zeile hinter letzten Zeile der Abfrage zwei Zeilen zurückhaben. die Abfrage geht ins Nirwana.
Wenn du das so machen willst, musst du vorher noch "$anzahl -= (x +1)" machen, wobei x die Anzahl der zeilen ist, die man haben möchte, und dann "SELECT * FROM `tabelle` LIMIT $anzahl, x"
 
Zuletzt bearbeitet:
Hast du einen Timestamp womit du den Zeitstempel des Datensatzes bestimmen kannst?

Wie wärs über nen subselect?

PHP:
select
	*
from
	(
	select
		column1,
		column2
	from
		table1 
	where
		active = 1
	order by
		timestamp desc
	limit 
		0,10
	) t1
order by
	t1.column1 asc

Somit hättest du die letzten 10 Datensätze anhand des timestamps absteigend sortiert und dieses Ergebnis dann aufsteigend nach Spalte "column1" sortiert ;)

wenn du keinen timestamp hast, dann vllt eine id mit auto increment? dann halt anstelle von order by timestamp desc => order by id desc

Mit php würde ich nicht rumwerkeln...wäre mir zu aufwendig, wenns so einfach mit sql geht.
 
2. die DESC-Ausgabe in eine Array speichern und selbiges später wieder ASC sortieren (oder ggf. mit array_unshift arbeiten)

Einfach array_reverse auf das Array anwenden --> 1 einfaches SQL Statement und 1 zusätzliche PHP Anweisung.
 
Um mal die Vorschläge zusammen zu fassen: es geht nur mit einer zweiten Abfrage oder mit einem Array!? :)

@ Cobinja: erklär doch mal, wie ich das machen soll? Ich bekomme meine Ausgabe e, d, c. Wie soll ich das jetzt mir PHP rückwärts durchgehen? Meine Ausgabenreihenfolge ist nunmal e, d, c.

Wie gesagt, wenn ich die Ausgabe in ein Array speichere, dann kann ich das natürlich anschließend andersrum sortieren - aber ich wollte es ja einfacher.
 
Also bevor du Daten in Arrays umkopierst, würde ich einfach (wie bereits vorgeschlagen) einen (Sub-)Query ausführen, welcher dir die Gesamtanzahl der Zeilen ausgibt. Musst dann noch die Anzahl der anzuzeigenden Zeilen abziehen und ggf. anpassen, sofern die Anzahl dadurch unter 0 fallen würde. (Siehe den Beitrag Cobinja).
So ein COUNT() Query ist extrem schnell und elegant. Die Perfomce steigert sich sogar noch mehr, wenn du keine WHERE Klausel im Query hast, da MySQL dabei direkt in die Tabellen Informationen schaut.

Eine optimalere Lösung fällt mir spontan auch nicht ein.
 
Mr. Snoot schrieb:
@ Cobinja: erklär doch mal, wie ich das machen soll? Ich bekomme meine Ausgabe e, d, c. Wie soll ich das jetzt mir PHP rückwärts durchgehen? Meine Ausgabenreihenfolge ist nunmal e, d, c.
PHP:
<?php

$sql = mysql_query( $query );
$data = array();
while( $s = mysql_fetch_array( $sql ) )
  $data[] = $s;

for( $i = sizeof( $data ) - 1; $i >= 0; $i-- )
  foo();

?>
du bekommst e, d, c und gehst aber nach c, d, e durch das array. alternati array_reverse benutzen und dann normal vorwärts durch das array gehen. allerdings is der schritt unnötig und verbraucht nur rechenzeit.
 
Cobinja schrieb:
@braumeister: das dürfte so nicht funktionieren. Der erste Parameter für Limit ist das (null-basierte) Offset. Deine zweite Abfrage möchte ab der ersten Zeile hinter letzten Zeile der Abfrage zwei Zeilen zurückhaben. die Abfrage geht ins Nirwana.
Wenn du das so machen willst, musst du vorher noch "$anzahl -= (x +1)" machen, wobei x die Anzahl der zeilen ist, die man haben möchte, und dann "SELECT * FROM `tabelle` LIMIT $anzahl, x"


stimmt, sorry. nicht drüber nachgedacht. war ein schnellschuss :P
 
Zurück
Oben