Abfrage Die letzten Einträge einer Tabell anzeigen (Distinct)
Ich würde mich über eine Gedächnisstütze zu folgender Problematik freuen:
Das Problem liegt in der korrekten & sinnvollen Formulierung der SQL Abfrage (MS SQL 2008).
Das Scenario:
Benutzer der Datenbank betrachten & bearbeiten eine Hand voll verschiedener Tabellen. z.B. Kunden, Aufträge, Mitarbeiter, ....
Da die Benutzer oft schnell (Anruf) in einen kürzlich bearbeiteten Datensatz springen soll (über eine entsprechende Front End Applikation) möchte ich dem jeweiligen Benutzer anzeigen lassen was er/sie zuletzt geöffnet hatte.
Zu diesem Zweck habe ich eine Tabelle angelegt die in etwas so aussieht:
id int --> Identitätsspezifikation (step 1) & Primärschlüssel
datum smalldatetime
benutzer varchar(50)
dokumenttyp char(1)
dokumentnummer int
zugriffstyp int
das datum soll auf die Minute den Zugriffszeitpunkt abscpeichern
benutzer ist der windows-Anmeldename
dokumenttyp ist z.B. 'k' für Kunde, 'a' für Auftrag usw.
dukumentnummer ist die ID des entsprechenden dokumenttyps
zugriffstyp 0- nur öffnen, 1 - ändern
Ich würde nun gerne eine Liste hieraus erhalten die den letzten Eintrag für einen Benutzer zuerst anzeigt ABER keine Doppelteinträge anzeigt. Also nur den LETZTEN ZUGRIFF auf den Datensatz wiedergibt. Das Datum sollte auch angezeigt werden. (Einträge der letzten 5 Tage)
Ich hatte nach einigem Gebastel eine funktionierende Lösung gefunden ( in diesem Fall soll nur der dokumenttyp Mitarbeiter angezeigt werden - mit einer Tabelle Mitarbeiter verknüpft):
SELECT x.nachname,x.vorname,y.datum,x.manr
FROM tbl_mitarbeiter x
INNER JOIN (SELECT TOP 100 PERCENT a.datum , a.dokumentnummer from base_zugriffe a INNER JOIN (SELECT MAX(id) As id FROM base_zugriffe WHERE benutzer LIKE '%" & Benutzer & "%' Group By dokumentnummer ) b on a.id=b.id where a.datum>'" & Date.Now.AddDays(-5) & "' AND dokumenttyp='m' order by a.datum DESC) y ON x.manr=y.dokumentnummer where x.nachname !='' order by y.datum DESC
jedoch entschleunigt diese den Datenbakzugriff erheblich! Diese Abfrage ist nach viel Trail & Error eroiert worden.... daher wohl unschön.
Ich würde mich über eine viel clevere Alternative freuen!
Vielen Dank im Voraus
Klaas
Das Problem liegt in der korrekten & sinnvollen Formulierung der SQL Abfrage (MS SQL 2008).
Das Scenario:
Benutzer der Datenbank betrachten & bearbeiten eine Hand voll verschiedener Tabellen. z.B. Kunden, Aufträge, Mitarbeiter, ....
Da die Benutzer oft schnell (Anruf) in einen kürzlich bearbeiteten Datensatz springen soll (über eine entsprechende Front End Applikation) möchte ich dem jeweiligen Benutzer anzeigen lassen was er/sie zuletzt geöffnet hatte.
Zu diesem Zweck habe ich eine Tabelle angelegt die in etwas so aussieht:
id int --> Identitätsspezifikation (step 1) & Primärschlüssel
datum smalldatetime
benutzer varchar(50)
dokumenttyp char(1)
dokumentnummer int
zugriffstyp int
das datum soll auf die Minute den Zugriffszeitpunkt abscpeichern
benutzer ist der windows-Anmeldename
dokumenttyp ist z.B. 'k' für Kunde, 'a' für Auftrag usw.
dukumentnummer ist die ID des entsprechenden dokumenttyps
zugriffstyp 0- nur öffnen, 1 - ändern
Ich würde nun gerne eine Liste hieraus erhalten die den letzten Eintrag für einen Benutzer zuerst anzeigt ABER keine Doppelteinträge anzeigt. Also nur den LETZTEN ZUGRIFF auf den Datensatz wiedergibt. Das Datum sollte auch angezeigt werden. (Einträge der letzten 5 Tage)
Ich hatte nach einigem Gebastel eine funktionierende Lösung gefunden ( in diesem Fall soll nur der dokumenttyp Mitarbeiter angezeigt werden - mit einer Tabelle Mitarbeiter verknüpft):
SELECT x.nachname,x.vorname,y.datum,x.manr
FROM tbl_mitarbeiter x
INNER JOIN (SELECT TOP 100 PERCENT a.datum , a.dokumentnummer from base_zugriffe a INNER JOIN (SELECT MAX(id) As id FROM base_zugriffe WHERE benutzer LIKE '%" & Benutzer & "%' Group By dokumentnummer ) b on a.id=b.id where a.datum>'" & Date.Now.AddDays(-5) & "' AND dokumenttyp='m' order by a.datum DESC) y ON x.manr=y.dokumentnummer where x.nachname !='' order by y.datum DESC
jedoch entschleunigt diese den Datenbakzugriff erheblich! Diese Abfrage ist nach viel Trail & Error eroiert worden.... daher wohl unschön.
Ich würde mich über eine viel clevere Alternative freuen!
Vielen Dank im Voraus
Klaas
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 136266
Url: https://administrator.de/forum/abfrage-die-letzten-eintraege-einer-tabell-anzeigen-distinct-136266.html
Ausgedruckt am: 13.04.2025 um 01:04 Uhr
1 Kommentar
Hallo Klaas,
erst mal vorab:
1. Ich arbeite mit SQL Server 2005, kann also sein, daß da noch was für SQL Server 2008 angepaßt werden müßte oder optimiert werden könnte.
2. Was ich da unten schreibe ist ungetestet, weil ich Deine Tabellen nicht da habe.
So, jetzt zur Abfrage:
Zwei Möglichkeiten fallen mir ein, welche die schnellere ist, müßtest Du ausprobieren. Nach meiner Erfahrung ist die Variante 1 meistens die schnellere, aber nicht immer.
Variante 1:
Variante 2:
"partition by benutzer, dokumenttyp, dokumentnummer" könnte hier durch "partition by dokumentnummer" ersetzt werden, weil ja auf benutzer und dokumenttyp eingeschränkt wird, aber sobald nach z.B. mehreren Dokumenttypen gesucht wird, braucht man das schon wieder.
Gruß, Mad Max
erst mal vorab:
1. Ich arbeite mit SQL Server 2005, kann also sein, daß da noch was für SQL Server 2008 angepaßt werden müßte oder optimiert werden könnte.
2. Was ich da unten schreibe ist ungetestet, weil ich Deine Tabellen nicht da habe.
So, jetzt zur Abfrage:
Zwei Möglichkeiten fallen mir ein, welche die schnellere ist, müßtest Du ausprobieren. Nach meiner Erfahrung ist die Variante 1 meistens die schnellere, aber nicht immer.
Variante 1:
select m.nachname,
m.vorname,
z1.datum,
m.manr
from tbl_mitarbeiter m
join base_zugriffe z1 on m.manr = z1.dokumentnummer
where z1.id = (select top 1 z2.id
from base_zugriffe z2
where z2.dokumentnummer = z1.dokumentnummer and
z2.benutzer like '%Benutzer%' and
z2.datum > dateadd (d, -5, convert (datetime, convert (varchar (50), getdate (), 112), 112)) and
z2.dokumenttyp = 'm'
order by z2.datum desc) and
m.nachname != ''
order by z1.datum desc
Variante 2:
select m.nachname,
m.vorname,
z.datum,
m.manr
from tbl_mitarbeiter m
join ( select *, row_number () over (partition by benutzer, dokumenttyp, dokumentnummer order by datum desc) sortnr
from base_zugriffe
where benutzer like '%Benutzer%' and
datum > dateadd (d, -5, convert (datetime, convert (varchar (50), getdate (), 112), 112)) and
dokumenttyp = 'm'
) z on m.manr = z.dokumentnummer and z.sortnr = 1
where m.nachname != ''
order by z.datum desc
Gruß, Mad Max