Hilfe bei SQL-Abfrage
Hi,
gegeben:
Tabelle "Objekte"
Tabelle "Eigenschaften"
Tabelle "Werte"
Ich habe verschiedene Objekte mit mehreren, verschiedenen Eigenschaften. Jedes Mal, wenn eine Eigenschaft eines Objekts geändert wird, dann soll der verherige Wert (und alle anderen, vorherigen) erhalten bleiben. Dazu wird in "Werte" ein neuer Datensatz erstellt, "ID" automatisch, "EigenschaftID" die ID der geänderten Eigenschaft, "Wert" der neue Wert und "Datum" das aktuelle Datum.
Wie kann ich jetzt mit jetzt alle Eigenschaften eines Objekts mit nur den aktuellsten Wert abfragen?
Was ich schon hinbekommen habe: Die Eigenschaften mit jeweils dem Datum des aktuellsten Werts liefern lassen.
Aber wie bekomme ich es hin, dass er mir statt dem max. Datum den Wert liefert?
Folgendes funktioniert nicht:
Da kommt:
Wie muss ich da vorgehen?
E.
gegeben:
- MS SQL Server 2005
- eine DB mit 3 Tabellen
Tabelle "Objekte"
- 2 Spalten: ID, Name
Tabelle "Eigenschaften"
- 3 Spalten: ID, ObjektID, Name
Tabelle "Werte"
- 4 Spalten: ID, EigenschaftID, Wert, Datum
Ich habe verschiedene Objekte mit mehreren, verschiedenen Eigenschaften. Jedes Mal, wenn eine Eigenschaft eines Objekts geändert wird, dann soll der verherige Wert (und alle anderen, vorherigen) erhalten bleiben. Dazu wird in "Werte" ein neuer Datensatz erstellt, "ID" automatisch, "EigenschaftID" die ID der geänderten Eigenschaft, "Wert" der neue Wert und "Datum" das aktuelle Datum.
Wie kann ich jetzt mit jetzt alle Eigenschaften eines Objekts mit nur den aktuellsten Wert abfragen?
Was ich schon hinbekommen habe: Die Eigenschaften mit jeweils dem Datum des aktuellsten Werts liefern lassen.
SELECT [Objekte].[Name], [Eigenschaften].[Name], Max([Werte].[Datum]) AS [MaxDatum]
FROM [Objekte]
INNER JOIN [Eigenschaften] ON [Eigenschaften].[ObjektID] = [Objekte].[ID]
INNER JOIN [Werte] ON [Werte].[EigenschaftID] = [Eigenschaften].[ID]
GROUP BY [Objekte].[Name], [Eigenschaften].[Name]
Aber wie bekomme ich es hin, dass er mir statt dem max. Datum den Wert liefert?
Folgendes funktioniert nicht:
SELECT [Objekte].[Name], [Eigenschaften].[Name], [Werte].[Wert]
FROM [Objekte]
INNER JOIN [Eigenschaften] ON [Eigenschaften].[ObjektID] = [Objekte].[ID]
INNER JOIN [Werte] ON [Werte].[EigenschaftID] = [Eigenschaften].[ID]
WHERE [Werte].[Datum] = Max([Werte].[Datum])
GROUP BY [Objekte].[Name], [Eigenschaften].[Name]
Da kommt:
In der WHERE-Klausel darf kein Aggregat auftreten, es sei denn, es befindet sich in einer Unterabfrage, die in einer HAVING-Klausel oder einer Auswahlliste enthalten ist, und die Spalte, die aggregiert wird, ist ein äußerer Verweis.
Wie muss ich da vorgehen?
E.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 330174
Url: https://administrator.de/contentid/330174
Ausgedruckt am: 25.11.2024 um 14:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo Emerics,
gab es bei SQL Server 2005 schon sowas wie "cross apply"? Dann würde das so funktionieren:
Ansonsten konnte man das früher so machen:
Gruß, Mad Max
gab es bei SQL Server 2005 schon sowas wie "cross apply"? Dann würde das so funktionieren:
SELECT [Objekte].[Name], [Eigenschaften].[Name], [Werte].[Datum], Werte.Wert
FROM [Objekte]
INNER JOIN [Eigenschaften] ON [Eigenschaften].[ObjektID] = [Objekte].[ID]
cross apply (select top (1) * from Werte where EigenschaftID = Eigenschaften.ID order by ID desc) as Werte
Ansonsten konnte man das früher so machen:
SELECT [Objekte].[Name], [Eigenschaften].[Name], [Werte].[Datum], Werte.Wert
FROM [Objekte]
INNER JOIN [Eigenschaften] ON [Eigenschaften].[ObjektID] = [Objekte].[ID]
INNER JOIN [Werte] ON [Werte].[ID] = (select top (1) ID from Werte where EigenschaftID = Eigenschaften.ID order by ID desc)
Gruß, Mad Max
Moin,
der Grund, warum dein zweites Statement nicht läuft ist der, dass du im SELECT-Segment das Feld [WERTE].[WERT] darstellen willst, es aber in die GROUP BY Clause nicht mit eingebunden hast.
Ansonsten müsstest du mit einem SubSelect im Inner Join arbeiten
Versuche das mal (ist nur "mal eben" zusammengedengelt):
Gruß
em-pie
Edit: zulange getippt
der Grund, warum dein zweites Statement nicht läuft ist der, dass du im SELECT-Segment das Feld [WERTE].[WERT] darstellen willst, es aber in die GROUP BY Clause nicht mit eingebunden hast.
Ansonsten müsstest du mit einem SubSelect im Inner Join arbeiten
Versuche das mal (ist nur "mal eben" zusammengedengelt):
SELECT
[Objekte].[Name]
, [Eigenschaften].[Name]
, [Tbl02].[Wert]
FROM
[Eigenschaften]
INNER JOIN [Objekte] ON
[Eigenschaften].[ObjektID] = [Objekte].[ID]
INNER JOIN (
SELECT [EigenschaftenID], [Wert], MAX[Datum] as MaxDatum
FROM Werte
GROUP BY [Datum]
) as Tbl02 ON
[Eigenschaften].[ID] = [Tbl02].[Werte]
Gruß
em-pie
Edit: zulange getippt
Hallo Emerics,
kann es sein, daß Du beim cross apply in der Unterabfrage auch "select top (1) Datum" geschrieben hast und nicht mehr "select top (1) *"? Beim cross apply solltest Du nur die Spalten im order by austauschen, nicht die Spalten im select.
Cross apply wird besser verarbeitet, deswegen solltest Du das verwenden.
Gruß, Mad Max
kann es sein, daß Du beim cross apply in der Unterabfrage auch "select top (1) Datum" geschrieben hast und nicht mehr "select top (1) *"? Beim cross apply solltest Du nur die Spalten im order by austauschen, nicht die Spalten im select.
Cross apply wird besser verarbeitet, deswegen solltest Du das verwenden.
Gruß, Mad Max