Benutzer mit den meisten Antworten
Aggregatfunktionen FIRST und LAST

Frage
-
Guten Tag,
ich glaube, diese Frage wurde zwar schon mehrfach gestellt bzw. beantwortet. Leider konnte ich keine zielführenden Informationen im www finden.
Ich habe eine sortierte Tabelle mit Messwerten und verschiedenen Zeitintervallen und möchte nach verschiedenen Zeitintervallen den ersten, den größsten, den kleinsten und den letzten Datensatz gruppiert darstellen.
Eine Beispieltabelle hat folgenden Aufbau:
CREATE TABLE [meineTabelle] ( [ID] [int] IDENTITY(1,1) NOT NULL, [Datum] [date] NULL, [Uhrzeit] [time](0) NULL, [Messwert] [float] NULL, ) ON [PRIMARY]
Bis vor kurzem habe ich die Daten noch in MS Access ausgewertet, nun möchte ich aber meinen Datenbestand mit dem SQL Server Express auswerten. Die Aggregatfunktionen FIRST und LAST werden leider in T-SQL nicht unterstützt.
Könnt Ihr mir einen Anstoß geben, wie ich die oben angegebenen Aggregatfunktionen auch in T-SQL umsetzen kann? Über jewede Hilfe würde ich mich freuen.
Vielen Dank
Micha
Antworten
-
Hallo Micha,
in Deinem Fall wäre das in etwa:
SELECT [Datum] ,(SELECT TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum -- Uhrzeit aufsteigend sortiert ORDER BY Uhrzeit) AS Erster , MAX([Messwert]) as [Max] , MIN([Messwert]) as [Min] ,(SELECT TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum -- Uhrzeit absteigend sortiert ORDER BY Uhrzeit DESC) AS Letzter -- Alternativ via MIN/MAX(ID) ,(SELECT -- TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum AND t2.ID = MIN([meineTabelle].ID) ) AS ErsterViaID ,(SELECT -- TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum AND t2.ID = MAX([meineTabelle].ID) ) AS LetzterViaID FROM [meineTabelle] GROUP BY [Datum] GO
Wobei ich zwei Varianten eingebaut habe:
Einmal über die Uhrzeit sofern innerhalb eines Tages aufsteigend,
was vermutlich am ehesten Deiner Absicht entspricht (und auch bei Access funktioniert)Die zweite Variante ermittelt die kleinste bzw. größte ID je Datum.
Was etwas näher am Verhalten von Access dran liegt, unter der Voraussetzung an den IDs wurde niemals rumgedreht
Was wiederum bei Access einfacher möglich wäre, als beim SQL Server (dort benötigt man IDENTITY_INSERT).
Füge mal einen Datensatz mit einer ID zwischen bestehende ein, der wird dann letzter ;-)Gruß Elmar
- Als Antwort markiert novus77 Dienstag, 21. Dezember 2010 20:05
Alle Antworten
-
Hallo,
Access FIRST und LAST sind nicht wirklich relational, da eine SQL-Abfrage (ohne ORDER BY) keine definierte
Ordnung hat, kann es auch keine erste oder letzte Zeile geben. Da eine Access MDB auf einem ISAM basiert,
funktioniert das dort (wenn auch mit einigen Annahmen).Im allgmeinen kann man aber FIRST durch MIN und LAST durch MAX ersetzen,
die Bestandteil von ANSI-SQL sind und auch Access kennt sie im übrigen.Eine erweiterte Möglichkeite (ab SQL Server 2005, nicht Access) wären die Fenster-Funktionen,
die man in Verbindung mit den Aggregatfunktionen kombinieren kann, siehe OVER-KlauselKonkrete Beispiele kann ich nachliefern, wenn Du einige Beispieldaten und einige exemplarische
Auswertungen (ggf. das Access SQL) zeigst.Gruß Elmar
-
Guten Abend Elmar,
vielen Dank für die schnelle Hilfe.
Hier mal ein paar Beispieldaten:
CREATE TABLE [dbo].[meineTabelle] ( [ID] [int] IDENTITY(1,1) NOT NULL, [Datum] [date] NULL, [Uhrzeit] [time](0) NULL, [Messwert] [float] NULL, ) ON [PRIMARY] GO INSERT INTO [dbo].[meineTabelle] VALUES ('12/16/2010' ,'08:01:00' ,23.25), ('12/16/2010' ,'09:12:00' ,23.00), ('12/16/2010' ,'16:44:00' ,23.63), ('12/17/2010' ,'07:15:00' ,23.79), ('12/17/2010' ,'10:32:00' ,23.55), ('12/17/2010' ,'19:51:00' ,23.63), ('12/18/2010' ,'08:20:00' ,23.50), ('12/18/2010' ,'13:21:00' ,23.49) GO
Diese Beispieldaten konnte ich in MS Access wie folgt abfragen (Annahme: die Daten sind mittels ORDER BY Uhrzeit sortiert):
SELECT [Datum] ,FIRST([Messwert]) as Erster ,MAX([Messwert]) as [Max] ,MIN([Messwert]) as [Min] ,LAST([Messwert]) as Letzter FROM [meineTabelle] GROUP BY [Datum]
Leider funktioniert das augenblicklich nicht mehr. Falls du mir wirklich ein paar Beispiele zeigen kannst, sage ich schon vorab vielen Dank.
Viele Grüße
Micha
-
Hallo Micha,
in Deinem Fall wäre das in etwa:
SELECT [Datum] ,(SELECT TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum -- Uhrzeit aufsteigend sortiert ORDER BY Uhrzeit) AS Erster , MAX([Messwert]) as [Max] , MIN([Messwert]) as [Min] ,(SELECT TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum -- Uhrzeit absteigend sortiert ORDER BY Uhrzeit DESC) AS Letzter -- Alternativ via MIN/MAX(ID) ,(SELECT -- TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum AND t2.ID = MIN([meineTabelle].ID) ) AS ErsterViaID ,(SELECT -- TOP (1) [Messwert] FROM meineTabelle AS t2 WHERE t2.Datum = meineTabelle.Datum AND t2.ID = MAX([meineTabelle].ID) ) AS LetzterViaID FROM [meineTabelle] GROUP BY [Datum] GO
Wobei ich zwei Varianten eingebaut habe:
Einmal über die Uhrzeit sofern innerhalb eines Tages aufsteigend,
was vermutlich am ehesten Deiner Absicht entspricht (und auch bei Access funktioniert)Die zweite Variante ermittelt die kleinste bzw. größte ID je Datum.
Was etwas näher am Verhalten von Access dran liegt, unter der Voraussetzung an den IDs wurde niemals rumgedreht
Was wiederum bei Access einfacher möglich wäre, als beim SQL Server (dort benötigt man IDENTITY_INSERT).
Füge mal einen Datensatz mit einer ID zwischen bestehende ein, der wird dann letzter ;-)Gruß Elmar
- Als Antwort markiert novus77 Dienstag, 21. Dezember 2010 20:05