Letzter Eintrag mit bestimmtem Wert

rezwiebel

Cadet 1st Year
Registriert
Juni 2008
Beiträge
11
Hallo zusammen,

ich verzweifel gerade an einer Abfrage:

Und zwar habe ich beispielsweise folgende Tabelle:

id wert
-- -----
1 1
1 5
1 1
1 1
2 1
2 1
3 1
3 5

Jetzt muss ich aus dieser Tabelle alle id's auslesen deren LETZTER Eintrag 1 war. Ergebnis müsste also sein: id1 und id2, id3 nicht, da war der letzte Eintrag ja 5.

Wie kann ich das mit SQL (SQL Server) machen?

Wäre klasse wenn mir einer helfen kann.

Gruß
René
 
SELECT id,wert FROM tabellenname WHERE wert = 1

Lange nicht gemacht, aber das müsste ich noch richtig hinbekommen haben, oder? :)

EDIT: Hm nachdem ich mir das nochmal durchgelesen habe, glaube ich dass du doch etwas anderes erreichen wolltest. Mein Post ist somit hinfällig
 
Danke trotzdem!

Ich möchte wirklich nur die, bei denen der letzte Eintrag den Wert 1 hatte.

So nach dem Motto:

SELECT DISTINCT id FROM Tabelle WHERE Last_Entry(wert)=1

Natürlich gibts die Funktion nicht, aber gibts was vergleichbares oder wie kann ich es mit einem Statement hinbekommen ohne anzufangen zu programmieren?
 
Wenn du keine Datums-Spalte hast, dann ist das ganze Unternehmen hinfällig. Zwar erscheinen die Einträge, wenn man die ORDER BY-Klausel weglässt, tatsächlich in der Regel in der Reihenfolge des hinzufügens, doch dafür wird keine Garantie übernommen und kann sich jederzeit ändern, zB durch das Einspielen eines Backups oder ein Update auf eine neue Datenbankversion.

Nochmal deutlich: Die Ausgabereihenfolge ist ohne ORDER BY absolut willkürlich, zumindest in sofern, dass keine bestimmte Regel beachtet wird. Man kann, soll und darf sich also nicht auf die Reihenfolge verlassen und es gibt auch keine Möglichkeit sowas abzufragen, da eine Menge von Tupeln keine Ordnung hat.

Je nach Datenbanksystem können Infos zur Einfügereihenfolge aber in den Metadaten stehen, in MySQL heißt diese Tabelle "information_schema", wenn ich mich recht erinnere und mit SQL Server habe ich zu wenig Erfahrung. Verlassen sollte man sich auf diese Verwaltungsdaten aber auch nicht.
 
Du erstellst eine autoincrement-Spalte. Dann sieht das ganze so aus:

Code:
  idx  id  wert
----- --- -----
   12   1     1
   13   1     5
   15   1     1
   16   1     1
   19   2     1
   22   2     1
   24   3     1
   26   3     5
Die Abfrage könnte dann so aussehen (in etwa, müsstest du ausprobieren):
Code:
select id, wert
from tabelle t

--vorherigen Datensatz ermitteln anhand höchster idx, die kleiner als aktuelle
where (select top 1 wert from tabelle t2 where t.idx>t2.idx order by idx desc) = '1'
 
Diese autoincrement-Spalte ist allerdings ein Spezialität von MySQL, die gibt es zwar auch in MS-SQL ich würde davon allerdings eher abraten.
Abgesehen das so ein Murks wie SELECT TOP 1 x FROM t ORDER BY x generell nie eine gute Lösung, da ein guter Optimizer diese Lösung selbst erstellt, manuell sollte man solche Scherze besser sein lassen.

Sinnvoller wäre es mit einem timestamp zu arbeiten, da der wenigstens noch eine zusätzliche Information bereitstellen kann, währen der autoincrement überhaupt gar keine sinnvolle Funktion hat. Da auch hier eigentlich fast jedes DBMS sein eigenes Süppchen kocht, mal ein Ansatz für MS-SQL der zumindest in anderen DBM-System ähnlich umgesetzt werden kann:
Code:
PK: id, changed

CREATE TABLE example (
	id int NOT NULL
,	changed datetime NOT NULL DEFAULT CURRENT_TIMESTAMP -- alternativ timestamp bei mssql
,	wert int NOT NULL

,	CONSTRAINT pk_example PRIMARY KEY (id, changed)
)

Herausfriemeln ginge dann nach dem folgenden Schema, das wirkt zwar etwas aufwändig (kann man natürlich auch anders schreiben, die hier vorgeschlagene Methode ist bei großen Datenmengen für Reporting-Abfragen aber meistens die schnellste, aber wenigen Tupeln sind meist andere Varianten sinnvoller) stellt aber sicher das das Ergebnis immer eindeutig ist, was letztlich wichtiger als die Geschwindigkeit ist:
Code:
SELECT e
FROM example AS e 
	INNER JOIN
		(SELECT id, MAX(changed) AS changed FROM example GROUP BY id) AS m
	ON (e.id = m.id AND e.changed = m.changed)
WHERE e.wert = 1
 
Zurück
Oben