Benutzer mit den meisten Antworten
Linq nach T-SQL übersetzen

Frage
-
Liebe Kollegen,
in einer Linq Abfrage habe ich das folgende Statement:
,cOpening = ( g.OrderByDescending(oItem => oItem.Exch_Date_Time).Last() ).B_S
wobei ich aus einer Gruppierung den Wert von B_S zu dem jeweilig kleinsten Exch_Date_Time Wert hole.
Ist so etwas auch in T-SQL möglich ?
cOpening = Min([Exch_Date_Time]).[B_S] wäre die Entsprechung, die natürlich nicht funktioniert
B_S kann den Wert 'B' oder 'S' haben. Ich hoffe, ich konnte mich klar ausdrücken .... Danke Uwe
- Bearbeitet uwefms Mittwoch, 13. März 2013 19:13
Antworten
-
Hallo Uwe,
wie schon vermutet, ist das über OVER und ROW_NUMBER() machbar:
CREATE TABLE Trans ( ID int NOT NULL PRIMARY KEY, Trans_Id int NOT NULL, Datum_Zeit datetime2 NOT NULL, B_S varchar(1) NOT NULL); INSERT INTO Trans (ID, Trans_ID, Datum_Zeit, B_S) VALUES (1, 1, '2013-11-01 12:13:23', 'B'), (2, 1, '2013-11-01 12:14:33', 'S'), (3, 1, '2013-11-01 12:14:43', 'S'), (4, 2, '2013-11-01 12:17:23', 'S'), (5, 2, '2013-11-01 12:19:23', 'B'), (6, 3, '2013-11-01 13:13:24', 'B'), (7, 3, '2013-11-01 13:13:53', 'S'); GO WITH TransCTE AS ( SELECT Trans.*, ROW_NUMBER() OVER ( PARTITION BY Trans_ID ORDER BY Datum_Zeit ASC) AS RowNumber FROM Trans ) SELECT * FROM TransCTE WHERE RowNumber = 1;
und dürfte simpler als LINQ sein, worüber ich jetzt aber nicht weiter reflektieren werde ;)
Gruß Elmar
- Als Antwort vorgeschlagen Ionut DumaModerator Mittwoch, 20. März 2013 14:47
- Als Antwort markiert Ionut DumaModerator Mittwoch, 3. April 2013 14:40
Alle Antworten
-
Hallo Uwe,
ich habe hier - LEIDER - sehr häufig mit LINQ und den extremen "Ausuferungen" in T-SQL zu tun. Ohne etwas mehr Details ist es schwierig, hier etwas zu sagen. Kannst Du bitte mal mittels PROFILER die Abfrage aus dem Entity Framework "aufzeichnen". Dann siehst Du das native SQL-Statement (was im Ergebnis eher grauenhaft aussehen wird). Dieses Statement poste bitte mal.
Was sich M$ bei LINQ gedacht hat, frage ich mich jeden Tag, wenn ich diese Statements sehe, die am SQL Server ankommen ;)
Uwe Ricken
MCSE - SQL Server 2012
MCSA - SQL Server 2012
MCITP Database Administrator 2005
MCITP Database Administrator 2008
MCITP Microsoft SQL Server 2008, Database Development
db Berater GmbH
http://www-db-berater.de
SQL Server Blog (german only) -
Hallo Uwe,
etwas mehr als das Fragment wäre hilfreich.
So wie der Schnipsel aussieht, könnte das mit OVER und ROW_NUMBER() - entspräche mehr dem LAST - gelöst werden.Wobei es effizienter sein dürfte anstatt rückwärts zu arbeiten - ORDER DESC und LAST - mit ORDER ASC und die erste Zeile zu nehmen.
Gruß Elmar
@Uwe Ricken: Man muss es nur beherrschen - SQL & LINQ - dann geht das schon;
leider wird öfter weder das eine noch das andere "gekonnt" ;))- Bearbeitet Elmar BoyeEditor Donnerstag, 14. März 2013 09:52
-
Elmar, Uwe,
vielen Dank für Eure Mühe
hier noch einmal das Problem ....
Ich habe eine SQL Tabelle:
ID Trans_Id Datum_Zeit B_S
------------------------------------------------
1 1 01.11.2013 12:13:23 B
2 1 01.11.2013 12:14:33 S
3 1 01.11.2013 12:14:43 S
4 2 01.11.2013 12:17:23 S
5 2 01.11.2013 12:19:23 B
6 3 01.11.2013 13:13:24 B
7 3 01.11.2013 13:13:53 sEs ist kein Problem in einer Abfrage z.B. nach Trans_Id und Datum zu gruppieren - ich erhalte dann 3 Sätze.
Mein Problem ist das Feld B_S, was nicht so einfach zu gruppieren ist. Ich brauche den B_S Wert zum jeweils
kleinsten Datum in der Gruppe. Die LINQ Expression konnte das.
Mittlerweile musste ich die Erzeugung der Gruppen in die DB verlagern - daher das aufgetretene ProblemMein Problem konnte ich übrigens durch einen JOIN lösen - gibt es vielleicht einen "besseren"
Weg innerhalb eine Gruppierung einen nicht gruppierbaren Wert zu ermitteln ?Danke
Uwe
-
Hallo Uwe,
wie schon vermutet, ist das über OVER und ROW_NUMBER() machbar:
CREATE TABLE Trans ( ID int NOT NULL PRIMARY KEY, Trans_Id int NOT NULL, Datum_Zeit datetime2 NOT NULL, B_S varchar(1) NOT NULL); INSERT INTO Trans (ID, Trans_ID, Datum_Zeit, B_S) VALUES (1, 1, '2013-11-01 12:13:23', 'B'), (2, 1, '2013-11-01 12:14:33', 'S'), (3, 1, '2013-11-01 12:14:43', 'S'), (4, 2, '2013-11-01 12:17:23', 'S'), (5, 2, '2013-11-01 12:19:23', 'B'), (6, 3, '2013-11-01 13:13:24', 'B'), (7, 3, '2013-11-01 13:13:53', 'S'); GO WITH TransCTE AS ( SELECT Trans.*, ROW_NUMBER() OVER ( PARTITION BY Trans_ID ORDER BY Datum_Zeit ASC) AS RowNumber FROM Trans ) SELECT * FROM TransCTE WHERE RowNumber = 1;
und dürfte simpler als LINQ sein, worüber ich jetzt aber nicht weiter reflektieren werde ;)
Gruß Elmar
- Als Antwort vorgeschlagen Ionut DumaModerator Mittwoch, 20. März 2013 14:47
- Als Antwort markiert Ionut DumaModerator Mittwoch, 3. April 2013 14:40