none
Linq nach T-SQL übersetzen RRS feed

  • 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
    Mittwoch, 13. März 2013 19:10

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

    Sonntag, 17. März 2013 16:33
    Beantworter

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)

    Donnerstag, 14. März 2013 06:00
  • 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" ;))

    Donnerstag, 14. März 2013 09:13
    Beantworter
  • 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  s

    Es 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 Problem

    Mein 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

    Sonntag, 17. März 2013 11:14
  • 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

    Sonntag, 17. März 2013 16:33
    Beantworter
  • Hallo Uwe,

    Hat Dir die Antwort von Elmar geholfen? Wenn ja bitte markiere diese als Antwort.

    Danke un Gruss,

    Ionut

    Mittwoch, 20. März 2013 14:48
    Moderator
  • Hallo Uwe,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Wenn nicht, neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.

    Danke und viele Grüße,
    Ionut

    Mittwoch, 3. April 2013 14:40
    Moderator