Mira: Nur neueste Datensätze finden

Guten Tag.

In einer (beispielhaften) Tabelle wird die Anwesenheit von Personen protokolliert. Da manche Personen ihren Personalausweis nicht bei sich tragen, werden Personen neben der Personalausweisnummer auch über ihren Vor- und Nachnamen identifiziert.

Der Eintrag zu einer Person soll dann als identische Person gelten, falls entweder die Ausweisnummer identisch ist oder es keine Ausweisnummer gibt, aber Vor- und Nachname identisch sind.

Die Anwesenheiten einer beliebigen Person bekomme ich mit

select vorname, nachname, ausweis, zeitpunkt from tabelle 
where 
   (ausweis is not null and ausweis = %s) 
   or (vorname = %s and nachname = %s)

Es kann vorkommen, dass diese Abfrage mehrere Personen liefert. Insbesondere soll keine Beachtung finden, dass die Tabelle mehrere Personen als eine Identität liefert oder mehrere Identitäten für eine Person gespeichert sind.

Frage: Wie bekomme ich die Datensätze (Ausweis, Namen, Zeitpunkt) der jeweils letzten Anwesenheit aller Personen, die diese Abfrage liefert?

Im Einsatz ist MariaDB, eine allgemeine Lösung wäre mir jedoch lieber.

  1. Hallihallo!

    In meiner Zeiterfassung habe ich das so gelöst, dass es noch zwei weitere Spalten "kommt" und "geht" gibt. Anwesend ist dann Jeder, für den ein Eintrag in "kommt" existiert, aber "geht" NULL ist.

    Falls zusätzliche Felder nicht in Frage kommen, würde mir noch einfallen, das Ergebnis absteigend nach dem Auto-Increment zu sortieren und die Ergebnismenge auf 1 zu limitieren. Das könnte aber Probleme geben, wenn zwischendurch auch mal Datensätze gelöscht werden und das DBMS dann die Lücken im Auto-Increment wieder auffüllt.

    EDIT: Ich habe gerade erst gemerkt, dass Du ja schon "zeitpunkt" mit speicherst. Also sollte es ein "ORDER BY zeitpunkt DESC LIMIT 1" (ungetestet) schon tun…

    Beste Grüsse, Tobias Hahner

  2. Hallo Mira,

    ich empfehle Dir schließe mich Tobias' Vorschlag bezüglich ORDER BY zeitpunkt DESC zusammen mit einem LIMIT 0,1 an.

    LIMIT ist spezifisch für MySql / MariaDB. Bei Microsoft heißt das TOP 1. Bei Oracle gibt's angeblich eine Syntax mit FETCH NEXT 1 ROWS ONLY. Bei Stackoverflow wurde auch der Einsatz der Ranking-Funktionen vorgeschlagen (OVER Klausel).

    Aber Du willst ja nur genau einen Treffersatz. Wenn die Abfrage nicht allzuviele Treffer liefert, könnte der ORDER BY am effizientesten sein.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hallo,

      danke euch beiden, aber …

      ich empfehle Dir schließe mich Tobias' Vorschlag bezüglich ORDER BY zeitpunkt DESC zusammen mit einem LIMIT 0,1 an.

      Aber Du willst ja nur genau einen Treffersatz.

      … nein, ich wollte mehrere, nämlich einen Datensatz je Person:

      Wie bekomme ich die Datensätze (Ausweis, Namen, Zeitpunkt) der jeweils letzten Anwesenheit aller Personen, die diese Abfrage liefert?

      Mit einer Sortierung nach Zeitpunkt und Beschränkung auf einen Datensatz bekomme ich nur die eine passende Person, deren Anwesenheit zuletzt festgestellt wurde.

      Beispiel: Frau Müller ist etwas schusselig und vergisst hin und wieder ihren Ausweis.

      Zeile Ausweis Vorname Nachname Tag
      1 Frau Müller Montag
      2 123 Frau Müller Dienstag
      3 123 Frau Müller Mittwoch
      4 123 Frau Müller Donnerstag
      5 Frau Müller Freitag
      6 Herbert Heinrich Sonnabend

      Die Suche nach der letzten Anwesenheit von ((Ausweis 123) oder (kein Ausweis und "Frau Müller")) soll Zeile 4 und 5 liefern.

      PS: Bitte nicht den Sinn multipler Identitäten hinterfragen, es handelt sich um ein Beispiel.

      1. Hallo Mira,

        da du uns deine reale Fachlichkeit verbirgst, kann ich dazu auch nichts sagen.

        Das „aller Personen“ hatte ich übersehen, sorry.

        Aber dem Beispiel muss ich noch auf die Zähne fühlen.

        • wenn eine Ausweisnummer da ist, ist dann auch immer der Name da?
        • ist der Zeitpunkt sortierbar? Wochentagnamen sortieren sich schlecht nach Zeit.
        • Ist "Frau Müller" im realen Fall eindeutig? Es führt ja ins Chaos, wenn Lieschen und Lenchen Müller herumlaufen, beide ohne Ausweis einchecken und als „Frau Müller“ erfasst werden.

        Eigentlich sollte dann ein einfacher GROUP BY über Ausweis, Vorname und Nachname mit MAX(Zeitpunkt) reichen.

        Rolf

        --
        sumpsi - posui - clusi