Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Datensätze nur anzeigen bei Veränderung

Begonnen von Biesdorfer, Oktober 12, 2015, 13:45:14

⏪ vorheriges - nächstes ⏩

Biesdorfer

Hallo Leute,
ich habe folgendes Problem.
Aus meiner Personaldatenbank will ich eine Abfrage so gestalten, dass mir als Ergebnis nur die Datensätze angezeigt werden, in denen für ein bestimmtes Feld eine Änderung eintritt.
Hinweis: Für jeden aktiven Beschäftigten liegt pro Monat ein Datensatz vor!
Hier mal als Beispiel:
Kollege Müller ist seit 01.2010 beschäftigt mit 38h/Woche. In 2012 macht Müller Elternzeit von 03.2012-04.2012 und reduziert seine wöchentl. Arbeitszeit auf 15h. Ab 05.2012 arbeitet er wieder 38h.
Das Ergebnis der Abfrage müsste wie folgt lauten, da immer in diesen Monaten sich die wöchtnl. Arbeitszeit geändert hat:
seit 01.2010 - 38h
seit 03.2012 - 15h
seit 05.2012 - 38h
Bitte dabei nicht auf die o.g. Datumsangaben beziehen, diese sind variabel.
Vielen Dank im voraus für eure Unterstützung!

datekk

Ich denke Du brauchst noch eine zweite Tabelle in welcher die Arbeitszeiten erfasst werden. Also z.B.

tbl_Arbeitszeiten

ID // ID_Mitarbeiter // Zeitraum_von  // Zeitraum_bis // Arbeitszeit

Die ID aus der Tabelle der Mitarbeiter wird mit dem Feld "ID_Mitarbeiter" von tbl_Arbeitszeiten verknüpft.

Dann lässt sich die Abfrage wie oben vorgesehen aus beiden Tabellen aufbauen.
Access 2016 mit SQL Server Backend. Bereits umgesetzt: Access mit MS SQL Backend,  ADODB Formularbindung, Streamen von Dateien zum SQL Server und zurück (Filestream), Drag&Drop Dateiupload zum Server, CTI / TAPI Integrierung in Access Anwendung - Nutzung auch über Remote Desktop, selbst aktualisierendes Access Frontend auf entfernten Rechnern (Upgrade). Berichte / Kreuztabellen mit SQL Server Backend, Mail Tagging, Outlook Steuerung über Access und umgekehrt // Grundwissen in .Net Core & Blazor Apps

ebs17

Ich tue mal so, als ob Datum wirklich ein Datum ist. Dann etwa so:
SELECT
   A.MA_ID,
   A.Datum,
   A.Arbeitszeit
FROM
   (
      SELECT
         MA_ID,
         Datum,
         Arbeitszeit
      FROM
         TabelleX
   ) AS A
      INNER JOIN
         (
            SELECT
               MA_ID,
               Datum,
               Arbeitszeit
            FROM
               TabelleX
         ) AS B
         ON A.MA_ID = B.MA_ID
            AND
         A.Datum = DateAdd("m", - 1, B.Datum)
            AND
         A.Arbeitszeit <> B.Arbeitszeit)
Mit freundlichem Glück Auf!

Eberhard

Biesdorfer

Hallo ebs17,

vielen Dank für deinen Ansatz. Ich habe diesen in meine Datenank eingebaut, erhalte aber immer die Fehlermeldung:
"Syntaxfehler in FROM-Klausel", mit der ich nicht weiter weiß.
Hier mal mein verwendeter Code:
SELECT
   A.MA_PNR,
   A.Seit,
   A.V_WAZ
FROM
   (
      SELECT
         MA_PNR,
         Seit,
         V_WAZ
      FROM
         qry_1021_PDDez_FTE_1_Test
   ) AS A
      INNER JOIN
         (
            SELECT
               MA_PNR,
               Seit,
               V_WAZ
            FROM
               qry_1021_PDDez_FTE_1_Test
         ) AS B
         ON A.MA_PNR = B.MA_PNR
            AND
         A.Seit = DateAdd("m", - 1, B.Seit)
            AND
         A.V_WAZ <> B.V_WAZ);

Erwähnt sei noch, dass es sich bei dem Feld "seit" um kein Datumsfeld an sich handelt. hier habe ich aus den monatlichen Datensätzen die Felder Jahr und Monat verkettet (z.B. 2015-10)
Könnte hier das Problem liegen?

MaggieMay

Hi,

als erstes würde ich mal die Klammern zählen, ob diese paarig sind.
Freundliche Grüße
MaggieMay

ebs17

Wie korrekt angemerkt ist die letzte schließende Klammer zuviel (kann schon mal passieren, wenn man eine Anweisung live und somit ungetestet schreibt).

Zitatkein Datumsfeld an sich
Warum nennst Du es dann Datum? Wenn man an eine Flasche Essig ein Etikett von Bordeaux klebt, bleibt es trotzdem Essig, jedenfalls für mich.

Aus welchem Grund verwendest Du keine richtigen Datumswerte (Datentyp Date)?
Wie würdest Du von 2005-01 auf den Vormonat schließen mittels einfacher Berechnung?

Hinweis: Wenn Du für die Monate in der Tabelle den Monatsersten als echtes Datum speicherst, kannst Du a) mit einem echten Datum arbeiten und rechnen und b) für die Ansicht mit einer einfachen Formatierung vielfältige Formate erzeugen wie yyyy-mm.

Anmerkung: qry_1021_PDDez_FTE_1_Test lässt auf eine Abfrage schließen. Da kann allerhand drin stecken ...
Mit freundlichem Glück Auf!

Eberhard

Biesdorfer

Hallo,

ja das hatte ich zwischenzeitlich auch schon bemerkt und korrigiert. Sowie das Datum musste ich auch noch anpassen und anstatt "-1" auf "+1" geändert.
Die Abfrage funktioniert nun auch einwandfrei - schon mal besten Dank dafür!!!
Was ich bei meinem ersten Post nicht beachtet hatte, dass ich aber auch noch den ersten Datensatz benötige, den es zu der Person gibt Also entweder von 01.01.2010 (kleinster Datensatz) oder ab Einstellung des Beschäftigten.
Habt ihr dazu eine Idee?Ich hatte mich jetzt lange im Netz damit versucht in meine Abfrage eine laufende Nummer einzubauen, was aber daran scheitert das es kein Autowert Feld gibt.

MaggieMay

Hi,
Zitatwas aber daran scheitert das es kein Autowert Feld gibt
ist denn das Datum nicht eindeutig pro Mitarbeiter?
Freundliche Grüße
MaggieMay

Biesdorfer

Ja ist es, deswegen versuche ich grad in den bestehenden SQL-Text noch die Funktion Min[Seit] einzubauen, was aber noch nicht von Erfolg gekrönt war  :-\
Meint ihr das ist der richtige Weg?

ebs17

#9
Etwas umgestellt und ergänzt:
SELECT
   A.MA_PNR,
   A.Seit,
   A.V_WAZ
FROM
   (
      SELECT
         MA_PNR,
         Seit,
         V_WAZ
      FROM
         qry_1021_PDDez_FTE_1_Test
   ) AS A,
   (
      SELECT
         MA_PNR,
         Seit,
         V_WAZ
      FROM
         qry_1021_PDDez_FTE_1_Test
   ) AS B
WHERE
   A.MA_PNR = B.MA_PNR
      AND
   A.Seit = DateAdd("m", + 1, B.Seit)
      AND
   A.V_WAZ <> B.V_WAZ
      OR
   EXISTS
      (
         SELECT
            NULL
         FROM
            (
               SELECT
                  MA_PNR,
                  MIN(Seit) AS MinSeit
               FROM
                  qry_1021_PDDez_FTE_1_Test
               GROUP BY
                  MA_PNR
            ) AS C
         WHERE
            C.MA_PNR = A.MA_PNR
               AND
            C.MinSeit = A.Seit
      )
Mit freundlichem Glück Auf!

Eberhard

Biesdorfer

Hallo ebs17,

vielen Dank für deine Mühe.
Ich habe den neuen Code in meine qry eingebaut, bekomme aber immer die "Fehlermeldung unbekannter Fehler des access-Datenbank Moduls"
Mein SQL-Syntax Prüftool sagt aber das der Code ok ist.
Liegt es eventuelle an der Abfrage aus der die Daten kommen?
Anbei mal die SQL der Abfrage:
SELECT qry_0021_Basis_Kopf.PNR_VNR_AK, qry_0021_Basis_Kopf.MA_PNR, qry_0021_Basis_Kopf.FTE_Vertrag, qry_0021_Basis_Kopf.FTE_K, qry_0021_Basis_Kopf.V_WAZ, "01." & [monat] & "." & [Jahr] AS Seit
FROM qry_0021_Basis_Kopf;


Viele Grüße

ebs17

Wie ich schon schrieb:
Zitat... Da kann allerhand drin stecken ...

"01." & [monat] & "." & [Jahr] AS Seit


Das ist Text (durch Aneinanderketten entsteht nur Text) und kein Datum.
Ein Datum könnte man mit DateSeriell erzeugen, besser würde man es aber der Tabelle entnehmen, denn Monat, Jahr uva. sind nur Formate eines Datums und daraus zu erzeugen.

Wie auch zu sehen: Die Datenherkunft der Abfrage ist wieder eine Abfrage. Wer weiß ...

Mit freundlichem Glück Auf!

Eberhard

Biesdorfer

#12
Hallo Leute,

seit meinem letzten Beitrag sind ein paar tage vergangen aber das Thema ist immer noch aktuell. Mein letztes Problem, das fehlen des 1. Datensatzes je Person konnte ich mittlerweile selbst lösen  ;)

Nun habe ich aber folgendes Problem:
Ich verwende den Code von ebs17, welcher auch super funktioniert (Danke nochmals)
Nun habe ich diesen Code für eine andere Fragestellung verwendet die den gleichen Sachverhalt abbilden soll, jedoch mit mehr Datenfeldern. Hierbei ist das Ergebnis der Abfrage immer leer.
Das liegt daran, dass sich von den Datenfeldern immer nur 1. Wert ändert aber nicht alle abgebildeten. Der Code von ebs17 zeigt aber nur die Datensätze wenn sich alle ausgewerteten Datenfelder ändern.
Habt ihr hierzu eine Idee, dass immer der Datensatz angezeigt wird wenn sich ein Eintrag geändert hat?
Hier mal mein COde:
SELECT A.MA_PNR, A.Seit, A.KST, A.KSTText, A.BE, A.FBR, A.KTR, A.KTRText, A.ST_FTE_K, A.Kopf, A.ST_Verteilung, A.ST_Rang
FROM (SELECT MA_PNR, Seit, KST, KSTText, BE, FBR, KTR, KTRText, ST_FTE_K, Kopf, ST_Verteilung, ST_Rang FROM qry_1021_PDDez_Stellenanteile_1) 
AS A INNER JOIN (SELECT MA_PNR, Seit, KST, KSTText, BE, FBR, KTR, KTRText, ST_FTE_K, Kopf, ST_Verteilung, ST_Rang FROM qry_1021_PDDez_Stellenanteile_1) 
AS B ON (A.KST<>B.KST) AND (A.KSTText<>B.KSTText) AND (A.BE<>B.BE) AND (A.FBR<>B.FBR) AND (A.KTR<>B.KTR) AND (A.KTRText<>B.KTRText) AND (A.ST_FTE_K<>B.ST_FTE_K) AND (A.Kopf<>B.Kopf) AND (A.ST_Verteilung<>B.ST_Verteilung) AND (A.ST_Rang<>B.ST_Rang) AND (A.Seit=DateAdd("m",+1,B.Seit)) AND (A.MA_PNR=B.MA_PNR);

ebs17

Verkettung der Kriterien:

AND ... immer alle
OR ... (mindestens) eines

Darauf könnte man auch selber kommen, war auch irgendwann mal Stoff in der Mathe-Mittelstufe.
Mit freundlichem Glück Auf!

Eberhard

Biesdorfer

Ja genau...
deshalb habe ich das natürlich auch schon in den verschiedensten Varianten ausprobiert. Leider geht es mit "OR" nicht. Dann erhalte ich plötzlich mehrere tausend doppelte Datensätze und wenn ich diese dann gruppiere erhalte ich wieder meine Ausgangsdaten als Ergebnis.
Aber ich will ja nur die in die Datensätze, wenn sich ein Wert ändert (außer das Datum natürlich, da das ja fortlaufend ist)