Nur den ersten DS pro Datum selektieren?
-
Hallo,
ich habe ein select, der mir eine gewisse Datenmenge zurück gibt. Dabei werden eine Menge DS pro Tag ausgegeben. Ich benötige lediglich den ersten DS pro Tag. Eine Eingrenzung auf die Uhrzeit bringt hier keinen Erfolg, da der erste DS am Tag mal nach 5sec. oder 12sec usw erscheint.
Habe aus dem Feld "DateTime" bereits das Datum gecastet (Datum_Kurz). Mit der Hoffnung damit arbeiten zu können. Doch leider komme ich hier nicht weiter.Hier mein Select:
SELECT temp.TagName ,DateTime ,Value , CAST(DateTime as Date) AS Datum_Kurz, vValue ,Unit = ISNULL(Cast(EngineeringUnit.Unit as VarChar(20)),'N/A') ,QualityDetail , StartDateTime From (SELECT * FROM History WHERE History.TagName IN ('042F00150_Q.PV') AND DateTime >= '20200421' AND DateTime <= '20200423') temp LEFT JOIN Tag ON Tag.TagName =temp.TagName LEFT JOIN AnalogTag ON AnalogTag.TagName =temp.TagName LEFT JOIN EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey WHERE temp.StartDateTime >= '20200421'
Gruß Torsten
-
Wird wohl auf min und group by rauslaufen, aber ohne Schema und ohne den konkreten SQL-Dialekt zu kennen ist das schwierig ...
-
Dann wirst du noch eine Gruppierung (
group by
) einbauen müssen, welche nur das Datum (nicht die Uhrzeit) beachtet.
-
Wo kann ich denn den SQL-Dialekt ablesen? Das ganze läuft auf einem MSSQL Server 2012.
Mit einem "group by" habe ich es schon versucht. Leider ohne Erfolg. Hier mal der select:SELECT temp.TagName ,DateTime ,Value , CAST(DateTime as Date) AS Datum_Kurz, vValue ,Unit = ISNULL(Cast(EngineeringUnit.Unit as VarChar(20)),'N/A') ,QualityDetail , StartDateTime From (SELECT * FROM History WHERE History.TagName IN ('042F00150_Q.PV') AND DateTime >= '20200421' AND DateTime <= '20200423') group by Datum_Kurz temp LEFT JOIN Tag ON Tag.TagName =temp.TagName LEFT JOIN AnalogTag ON AnalogTag.TagName =temp.TagName LEFT JOIN EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey WHERE temp.StartDateTime >= '20200421'
Bekomme dann leider diesen Fehler:
Incorrect syntax near the keyword 'group'.
-
@torsten_156 sagte in Nur den ersten DS pro Datum selektieren?:
Wo kann ich denn den SQL-Dialekt ablesen?
Da
@torsten_156 sagte in Nur den ersten DS pro Datum selektieren?:
MSSQL Server 2012
-
Auch das hier geht nicht:
......LEFT JOIN EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey WHERE temp.StartDateTime >= '20200421' GROUP by Datum_Kurz
Bekomme diesen Fehler:
Invalid column name 'Datum_Kurz'.
-
@torsten_156 sagte in Nur den ersten DS pro Datum selektieren?:
Bekomme diesen Fehler:
Invalid column name 'Datum_Kurz'.group by nimmt keinen Spaltenalias. Unabhängig davon: es wird wohl nicht reichen, irgendwo ein group by hinzuschmieren.
-
@manni66 sagte in Nur den ersten DS pro Datum selektieren?:
group by nimmt keinen Spaltenalias.
Also komme ich hier mit einem "group by" schon mal nicht weiter. Wie würde ich das hier dann mit einem "min" machen müssen?
-
@manni66 sagte in Nur den ersten DS pro Datum selektieren?:
aber ohne Schema und ohne den konkreten SQL-Dialekt zu kennen ist das schwierig ...
-
Das Schema kenne ich nicht. Komme ich auch so einfach nicht ran!
-
@torsten_156 sagte in Nur den ersten DS pro Datum selektieren?:
Das Schema kenne ich nicht. Komme ich auch so einfach nicht ran!
???
-
Bin halt nicht der DB-Admin. Darf lediglich auf die DB Mittels "SQL Manager" zugreifen.
-
@torsten_156
Du weißt aber schon, was ein Datenbankschema ist, oder?
-
Ups, hatte das Schema wohl mit den DB-Objekten und deren Relationen zueinander verwechselt.
Das Schema hier wäre dann "dbo".
-
@torsten_156
Nein, das Schema beschreibt die Struktur deiner Datenbank (Tabellen, Felder, Stored Procedures, usw. Eigentlich alles, was keine Daten sind). Wenn du das Schema nicht kennst, kannst du auch keine Abfrage formulieren, denn dazu brauchst du ja Tabellen- und Spaltennamen.
Hab jetzt den ganzen Thread nicht gelesen, aber kannst du vllt erst einen View erzeugen, die Abfrage gegen den View machen und anschließend den View zerstören?
-
Also ich zeig die mal ein verkleinertes Beispiel:
create table history (id int, dt datetime, groupvalue int); insert into history (id, dt, groupvalue) values (1, "2019-02-02 11:00:00", 1), (2, "2019-02-02 11:01:00", 1), (3, "2019-02-02 11:02:00", 2), (4, "2019-02-02 11:01:00", 2); select history.* from history join (select groupvalue, max(dt) max_val from history group by groupvalue) tab_max on tab_max.groupvalue = history.groupvalue and tab_max.max_val = history.dt;
Ergibt:
id|dt|groupvalue 2|2019-02-02 11:01:00|1 3|2019-02-02 11:02:00|2
Du wählst also als erstes in dem subjoin aus, welches das maximale Element pro Gruppe ist und joinst das dann mit derselben Tabelle on Gruppierungskriterium und Datum.
Gut, statt max solltest du hier wohl min wählen. Aber ich hoffe, das Prinzip ist klar.
Gibt bestimmt auch noch andere Lösungen - ggf. gibt es für das jeweile Datenbanksystem was besseres/effizienteres.
-
Mit MS SQL Server kannst du das mit PARTITION BY auch ohne JOIN machen.
Siehe https://stackoverflow.com/questions/6841605/get-top-1-row-of-each-group