none
SQL Abfrage RRS feed

  • Frage

  • Hallo liebe Gemeinde,

    ich habe zwei Anfragen. Vielleicht kann man auch beide mit einem Ansatz lösen.

    Ich habe eine Tabelle:

    IF OBJECT_ID ('TEMPDB..#TEST', 'U') IS NOT NULL DROP TABLE #TEST
    CREATE TABLE [DBO].[#TEST] (
        [ID]      INT NOT NULL,
        [REMARK]  VARCHAR(5) NOT NULL,
        [ST_DATE] DATE NULL
        )

    mit folgender Datenausprägung

    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(1337, 'ABC', '2012-11-9')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(1337, 'ERT', '2012-11-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(1337, 'UIO', '2012-11-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(245, 'SDF', '2012-12-9')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(245, 'RER', '2012-10-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(245, 'VVV', '2012-11-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(245, 'RWE', '2012-08-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(556, 'RED', '2012-07-9')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(556, 'BLUE', '2012-09-5')
    INSERT INTO [DBO].[#TEST]([ID], [REMARK], [ST_DATE])
        VALUES(556, 'BLACK', '2012-12-5')

    1. Ich möchte nun zu jeder ID das Remark haben mit dem niedrigsten ST_DATE.

    Das Ergebnis sieht dann wie folgt aus:

    ID REMARK ST_DATE
    245 RWE 2012-08-05
    556 RED 2012-07-09
    1337 ERT 2012-11-05

    2. Ich möchte die Tabelle um ein Feld erweitern (Sequenz). Die Sequenzen sollen dann pro ID die ST_DATE durch Sequenzieren (falls es das Wort überhaupt gibt). Wenn ein Datum in einer ID mehrfach vorkommt, sollen diese trotzdem ein unterschiedliche Sequenz bekommen. Die Reihenfolge ist bei gleichen Datum egal.

    Ist das Problem so transparent geschildert? Kann mir bitte jemand helfen, ich stehe hierbei echt auf dem Schlauch.

    Vielen Dank und liebe Grüße,

    FranzL

    PS.: ich nutze SQL Server 2008



    Montag, 5. November 2012 13:09

Antworten

  • Du kannst auch beides zusammen lösen:

    with cte
    as
    (
    Select ID, ST_DATE, REMARK, row_number() OVER(PARTITION BY ID ORDER BY
    ST_DATE) As rrn
    from #TEST
    )
    Select c1.ID, c1.ST_DATE, c1.rrn, c2.REMARK    as Remark_Min
    from cte c1
    inner join cte c2
    on c1.ID = c2.ID
    and c2.rrn = 1
    order by id, ST_DATE;

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    • Als Antwort markiert FranzLBerlin Montag, 5. November 2012 14:14
    Montag, 5. November 2012 14:08

Alle Antworten

  • Hallo Franz,

    zu der ersten Frage:

    SELECT ID, MIN(ST_DATE) AS ST_DATE FROM #TEST GROUP BY ID

    Ich verstehe irgendwie nicht ganz, was du bei der 2. Aufgabe machen möchtest.

    Kannst du dort ebenfalls eine Beispielausgabe erstellen, so wie dein gewünschtes Ergebnis aussehen soll?

    Grüße

    Oliver

    Montag, 5. November 2012 13:15
  • Die Antwort auf die zweite Frage sollte ein ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ST_DATE) sein.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu



    Montag, 5. November 2012 13:24
  • Hallo Oliver vielen Dank für deine Antwort,

    aber bei deinem Select fehlt mir noch das Remark-feld :S

    2. habe ich mit dem Tipp von Chritoph gelöst bekommen. Vielen dank dafür @Christoph

    1. könnte ich zwar nun lösen in dem ich ein Select mache mit der Where Klausel" WHERE SEQUENZ = 1 aber hierfür müsste ich immer erst die Tabelle mit RowCount neu aufbauen.

    Von daher bräuchte ich für 1. noch eine alternative.

    Liebe Grüße und danke für eure Mühe.

    Montag, 5. November 2012 13:41
  • Du kannst auch beides zusammen lösen:

    with cte
    as
    (
    Select ID, ST_DATE, REMARK, row_number() OVER(PARTITION BY ID ORDER BY
    ST_DATE) As rrn
    from #TEST
    )
    Select c1.ID, c1.ST_DATE, c1.rrn, c2.REMARK    as Remark_Min
    from cte c1
    inner join cte c2
    on c1.ID = c2.ID
    and c2.rrn = 1
    order by id, ST_DATE;

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    • Als Antwort markiert FranzLBerlin Montag, 5. November 2012 14:14
    Montag, 5. November 2012 14:08
  • Falls Du nur das erste Problem lösen willst, geht es z. B. so:

    Select id, ST_DATE, REMARK
    from #test t1
    where ST_Date in ( Select min(t2.ST_DATE) from #TEST t2 where t2.ID =
    t1.ID);

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Montag, 5. November 2012 14:19
  • Hallo Chritoph,

    ich bin verblüfft. Für mich ist aber nicht transparent wie dieses Statement funktioniert bzw. wieso das gewünschte Ergebnis rauskommt. Könntest du mir das mal erklären wie das Statement funktioniert?

    Liebe Grüße,

    FranzL

    Dienstag, 6. November 2012 10:22
  • Hallo Franz, Du meinst wahrscheinlich das erste Statement:

    with cte
    as
    (
    Select ID, ST_DATE, REMARK, row_number() OVER(PARTITION BY ID ORDER BY
    ST_DATE) As rrn
    from #TEST
    )
    Select c1.ID, c1.ST_DATE, c1.rrn, c2.REMARK        as Remark_Min
    from cte c1
    inner join cte c2
    on c1.ID = c2.ID
    and c2.rrn = 1
    order by id, ST_DATE;

     In der CTE (Common Table Expression) werden die Zeilen durchnummeriert (nach ID partitioniert und in der Reihenfolge der Zeitpunkte).
    Das darauf aufbauende Select zeigt Dir die Daten mit den Nummern an. Das ist die Tabelle c1.
    Wenn man nun c1 anhand der ID (über die wir ja auch Partitionieren) mit sich selber joined (c2) und hierbei nur die Sätze mit der rrn = 1 aus der zweiten Tabelle verwendet, werden also nur die Top-Treffer aus c2 jeder anderen Zeile aus c1 zugeordnet.

    HTH!
     Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu

    Dienstag, 6. November 2012 11:57