none
Verzwickte SQL-Abfrage...

    Frage

  • Hallo,

    eine Abfrage von mir ergibt folgende Tabelle.

    Date        | Name      | IN (Boolean)
    ------------+-----------+-------------
    13.03.2013  | John Doe |  True
    12.03.2013  | John Doe  |  False
    13.03.2013  | Mr. Green |  True
    14.03.2013  | Mr. Green |  False
    13.03.2013  | Mr. Pink  |  True
    12.03.2013  | Mr. Pink  |  False

    Ich möchte nur alle Namen in denen beim letzten Zeitpunkt der IN-Wert = False ist.
    Das wäre in obigem Fall nur Mr. Green

    Date        | Name      | IN (Boolean)
    ------------+-----------+-------------
    14.03.2013  | Mr. Green |  False

    Hat jemand eine Idee, ich stehe gerade total auf dem Schlauch...
    Mittwoch, 13. März 2013 14:38

Antworten

  • Danke für die schnellen Antworten!

    Ich habe es dann aber doch anders gelöst. Im Prinzip habe ich die Abfrage, die zu der ersten Tabelle führt noch einmal ausgeführt, jedoch ohne Gruppierung über IN. Somit habe ich nun zwei Tabellen.
    Die erste wie oben abgebildet.
    Die zweite enthält NUR die maximaldaten Gruppiert nach Namen.
    Diese beiden Tabellen habe ich nun über RIGHT JOIN miteinander verknüpft, so dass nur die maximaldaten, Namen und IN-Werte bleiben.
    Eine übergeordnete Abfrage filtert mir dann noch alle True IN-Werte  heraus - fertich!

    Bin schon bisschen stolz auf mich, zumal zu dem Datum-Field noch ein Zeit-Field gehört, diese mussten auch noch vereint werden. War schon ziemlich tricky.

    Übrigens haben die Spaltennamen natürlich nicht die o.a. Namen - ist nur Demo.

    Ich arbeite mit ACCESS, ich denke das CTE da nicht geht...

    Wen es interessiert, hier die komplette Abfrage:

    SELECT A.datum_zeit, A.personal_key
    FROM (SELECT max(DATEADD('n',zeit, datum)) as datum_zeit, personal_key, kommen FROM stechuhr GROUP BY personal_key, kommen) AS A
    RIGHT JOIN (SELECT max(DATEADD('n',zeit, datum)) as datum_zeit, personal_key FROM stechuhr GROUP BY personal_key) AS B ON B.personal_key=A.personal_key AND B.datum_zeit=A.datum_zeit
    WHERE kommen = False

    Mittwoch, 13. März 2013 17:35

Alle Antworten

  • Hallo DEKOforce!
     
    Ich würde das mit einer Common Table Expression (CTE) und der ROW_NUMBER-Funktion lösen:
     
       WITH CTE AS
          (
             SELECT
                   ROW_NUMBER() OVER
                      (
                         PARTITION BY
                            [Name]
                         ORDER BY
                            [Date] DESC
                      ) AS LfdNr,
                   [Date],
                   [Name],
                   [IN]
                FROM
                   MyTable
          )
       SELECT
             [Date],
             [Name]
          FROM
             CTE
          WHERE
             LfdNr = 1
             AND [IN] = 0;
     
    HTH
     
    Grüße
    Thomas
     
    --
    Any problem in computer science can be solved with another layer
    of indirection. But that usually will create another problem.
                                       David Wheeler
     
    Mittwoch, 13. März 2013 14:57
  • Hi,

    das würde bspw. so gehen:

    WITH Query AS
    (
    SELECT   MAX( [Date] ) AS [Date],
             Name
    FROM     DEKOForce
    GROUP BY Name
    )
    SELECT   *
    FROM     DEKOForce d
    WHERE    EXISTS ( SELECT [Date], Name FROM Query q WHERE d.Date = q.Date AND d.Name = q.Name )
    AND      [IN] = 0
    
    Allerdings solltest Du dir dringend Gedanken um die Benennung deiner Spaltennamen (und wahrscheinlich auch der Tabellennamen, ...) machen. IN, Date, ... sind Schlüsselworte, nicht nur in SQL. Auch wenn es über [...] geht, macht es wenig Sinn, als Objektnamen reservierte Worte zu verwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 13. März 2013 15:04
    Moderator
  • Danke für die schnellen Antworten!

    Ich habe es dann aber doch anders gelöst. Im Prinzip habe ich die Abfrage, die zu der ersten Tabelle führt noch einmal ausgeführt, jedoch ohne Gruppierung über IN. Somit habe ich nun zwei Tabellen.
    Die erste wie oben abgebildet.
    Die zweite enthält NUR die maximaldaten Gruppiert nach Namen.
    Diese beiden Tabellen habe ich nun über RIGHT JOIN miteinander verknüpft, so dass nur die maximaldaten, Namen und IN-Werte bleiben.
    Eine übergeordnete Abfrage filtert mir dann noch alle True IN-Werte  heraus - fertich!

    Bin schon bisschen stolz auf mich, zumal zu dem Datum-Field noch ein Zeit-Field gehört, diese mussten auch noch vereint werden. War schon ziemlich tricky.

    Übrigens haben die Spaltennamen natürlich nicht die o.a. Namen - ist nur Demo.

    Ich arbeite mit ACCESS, ich denke das CTE da nicht geht...

    Wen es interessiert, hier die komplette Abfrage:

    SELECT A.datum_zeit, A.personal_key
    FROM (SELECT max(DATEADD('n',zeit, datum)) as datum_zeit, personal_key, kommen FROM stechuhr GROUP BY personal_key, kommen) AS A
    RIGHT JOIN (SELECT max(DATEADD('n',zeit, datum)) as datum_zeit, personal_key FROM stechuhr GROUP BY personal_key) AS B ON B.personal_key=A.personal_key AND B.datum_zeit=A.datum_zeit
    WHERE kommen = False

    Mittwoch, 13. März 2013 17:35
  • Hi,

    nuja, wirklich was anderes als das, was Thomas und meine Wenigkeit vorgeschlagen haben, ist das nu auch nicht :)

    Der Hinweis auf Access wäre vorher sinnvoller gewesen (abgesehen davon, dass Du hier im SQL Server Forum gepostet hast und SQL Server nunmal nichts mit Access zu tun hat, daher ist http://social.msdn.microsoft.com/Forums/de-DE/accessde/threads das bessere Forum für Fragen hierzu)

    Aber Hauptsache ist, dass es funktioniert.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 13. März 2013 18:22
    Moderator
  • Dann verschieben wir es doch dort hin..
    Donnerstag, 14. März 2013 23:19
    Moderator
  • Dann verschieben wir es doch dort hin..

    Nuja, ich kanns nicht verschieben, da ich hier kein Mod bin :)

    Daher: Walte deines Amtes :)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 14. März 2013 23:49
    Moderator