verwendetes Datenbanksystem: microsoft sql server 2005
hi,
Ausgangssitutation:
eine Tabelle, welche mehrere Datenstätze enthält. ein Datenstatz hat dabei eine eigene ID (foreign key) und kann an mehrereren Orten (foreing key) auftauchen, jedoch nie zu einem Zeitpunkt an zwei orten gleichzeitig. Jeder Datensatz besitzt ein Datum (dd/mm/yyyy/ hh:mm/ss), welches bestimmt zu welcher zeit es an dem ort eingegangen ist.
N1 | O1 | 01.01.2009
N1 | O2 | 01.04.2009
N2 | O3 | 01.02.2009
N1 | O4 | 01.06.2009
N2 | O2 | 01.03.2009
Gesucht:
ein select, welches mir die Informationen zurückgibt, welcher Name sich zum aktuellen Zeitpunkt x an einem Ort o befindet
bsp.
SELCECT *
FROM tbl...
WHERE IDOrt = ##
AND IDName sich zum aktuellen zeitpunkt befindet
N1 | O1 | 01.06.2009
N2 | O2 | 01.03.2009
hat irgendjemand ne idee oder nen anstatz wie man das realisieren kann?
greets
mex
que? como? no entiendo!!!!!
Hallo!
Also ganz verstehe ich deine Frage leider nicht...
Wenn du wissen willst, die du den aktuellen Zeitpunkt in MSSQL abfragst:
NOW()
also WHERE datCreated = NOW()
Oder, wenn du deine Daten als string gespeichert hast, wie es aussieht:
WHERE datCreated = Format(now(), "dd-MM-yyyy")
ich suche etwas in der art:
select IDName
from tbl...
where datum = aktuellste
and ort = xy
so verständlicher?
now bezieht sich doch auf den aktuellen zeiptunkt. problem, wenn ein datensatz bereits seit einer woche an einem ort ist - dann ist now doch nicht richtig eingesetzt. oder?
que? como? no entiendo!!!!!
Oder auch MAX(Datum) mit GROUP BY Ort
So verstehe ich es jedenfalls.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
so,
danke erstmal für die hilfe und entschuldigt die formulierung der frage, ist (zumindest geht es mir so) nicht immer ganz einfach sowas in einfache worte zu fassen (hoffe damit bin ich nicht allein 😉
hier meine lösung (die auch funktioniert 😉
select *
from tbl...
where IDOrt like '...'
and datum IN ( select max(datum)
from tbl...
group by strIDName);
für weitere anregungen oder fragen, bin ich natürlich immer offen
danke nochmal für die schnellen posts
saludos
mex
que? como? no entiendo!!!!!
für weitere anregungen oder fragen, bin ich natürlich immer offen
Du wolltest es ja nicht anders... 😉
select *
from tbl...
where IDOrt like '...'
and datum IN ( select max(datum)
from tbl...
group by strIDName);
Das Statement läuft in Probleme sobald man mehr als mal mehr als einen Namen sucht. Man kann die Kriterien von außen nach innen durchreichen um eine Relation herzustellen. Das GROUP BY kann dafür wegfallen:
select *
from tbl t1
where IDOrt like '...'
and datum IN ( select max(datum)
from tbl
--- Hier
WHERE IDName = t1.IDName);
Wie Khalid bereits geschrieben hat wäre meistens MAX der beste Weg das zu lösen, aber ohne Sub-Query:
select
IDName,
MAX(datCreated)
from tbl...
where IDOrt like '...'
group by IDName
Problematisch wird MAX jedoch wenn man den gesamten Datensatz benötigt und nicht nur eine ID. In dem Fall ist meistens der beste und performanteste Weg eine CTE mit einer ROW_NUMBER zu verwenden:
; WITH cte (IDName, IDOrt, datCreated, RowNum) AS
(
SELECT
IDName,
IDOrt,
datCreated,
ROW_NUMBER() OVER (PARTITION BY IDName ORDER BY datCreated DESC)
FROM tbl
)
SELECT
IDName,
IDOrt,
datCreated
FROM cte
WHERE RowNum = 1
Das MAX Problem ließe sich jetzt noch über einen CROSS APPLY lösen, ist aber normalerweise weniger performant.
Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+
Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.