jensgebken
Goto Top

Access: Abfrageproblem

Hallo Gemeinschaft,

habe mal wieder ein Abfrageproblem

habe zwei Tabellen

tbl_Betreuer
id_Nachname_Vorname....

tbl_Leistungsnachweis
id_id-Betreuer_Monat_Jahr_Stunden.......

nun möchte ich eine Abfrage haben, die folgendes kann

ich möchte nur die Betreuer angezeigt bekommen, die in den letzten 3 Monaten keinen Leistungsnachweis abgegeben habe

könnt ihr mir bitte dabei helfen

Content-ID: 62400474171

Url: https://administrator.de/contentid/62400474171

Ausgedruckt am: 22.11.2024 um 04:11 Uhr

em-pie
em-pie 24.01.2024 um 08:32:12 Uhr
Goto Top
Moin,

LEFT JOIN()
Und
Where IS Null

Damit kommst du weiter.
Wenn es hakt: poste hier deinen bisherigen Ansatz und wir schauen drüber.

Weiterhin Grundlagen SQL…
jensgebken
jensgebken 24.01.2024 aktualisiert um 08:37:52 Uhr
Goto Top
SELECT tbl_Betreuer.ID, tbl_Betreuer.Nachname, tbl_Betreuer.Vorname, tbl_Leistungsnachweis.id_Patient, tbl_Leistungsnachweis.ID
FROM tbl_Betreuer LEFT JOIN tbl_Leistungsnachweis ON tbl_Betreuer.ID = tbl_Leistungsnachweis.id_Betreuer
WHERE (((tbl_Leistungsnachweis.ID) Is Null) AND ((tbl_Betreuer.Deaktiv)=False));

ich weiss nur nicht, wie ich das mit den 3 Monaten reinbekommen soll
Blackmann
Blackmann 24.01.2024 um 08:54:45 Uhr
Goto Top
Moin,

was versteckt sich denn hinter 'id_id-Betreuer_Monat_Jahr_Stunden.......', Zahl, Datum, Text

BG BM
jensgebken
jensgebken 24.01.2024 aktualisiert um 09:00:23 Uhr
Goto Top
id - eindeutige Nummer der Leistungsnachweise - Zahl
id_Betreuer - Verweis zum Betreuer - Zahl
Monat - Monat in dem er bearbeitet hat - Zahl
Jahr - in dem er gearbeitet hat - Zahl
Stunden - Anzahl der Stunden - Zahl
Blackmann
Blackmann 24.01.2024 um 12:07:30 Uhr
Goto Top
Mahlzeit,

beide Tabellen über referentielle Integrität verbunden, dann Abfrage erstellt wie folgt:

SELECT tbl_Betreuer.id_Nachname_Vorname, tbl_Leistungsnachweis.Monat, tbl_Leistungsnachweis.Jahr, tbl_Leistungsnachweis.Stunden
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE ((Month(Now())-[Monat]>3));

unter der Annahme, dass das Feld Monat der Nachweis für den letzten Leistungsnachweis enthält, also dann die Diff zu Heute.

MfG BM
em-pie
em-pie 24.01.2024 um 12:21:53 Uhr
Goto Top
@Blackmann
Du setzt voraus, dass sein Feld "Monat" eine Zahl beinhaltet.
Bei seinen zahlreichen Threads hier meine im Kopf zu haben, dass dort "Januar", "Februar", "März", ..., "Dezember" steht

Und ein "(1 - November) > 3" wird immer auf die Nase fallen.

Ohne Beispieldaten bin ich hier jetzt im übrigen raus, den @jensgebken liefert keine Daten, um sich helfen zu lassen.
Blackmann
Blackmann 24.01.2024 um 12:35:31 Uhr
Goto Top
@em-pie, genau

Zitat von @jensgebken:

Monat - Monat in dem er bearbeitet hat - Zahl

Ich hätte in einem Feld sogar das komplette letzte Nachweisdatum integriert.

MfG BM
em-pie
em-pie 24.01.2024 um 12:51:25 Uhr
Goto Top
Zitat von @Blackmann:

@em-pie, genau

Zitat von @jensgebken:

Monat - Monat in dem er bearbeitet hat - Zahl

Ich hätte in einem Feld sogar das komplette letzte Nachweisdatum integriert.

MfG BM
Wie jeder Mensch, der mit Daten (Plural eines Kalenderdatums) arbeitet… nunja…
jensgebken
jensgebken 24.01.2024 um 13:16:42 Uhr
Goto Top
Im Monat steht eine Zahl

Ich kann kein Kalenderdatum nehmen, weil im Leistungsnachweis immer der Monat gemeint ist, in dem gearbeitet wurde - manchmal kommt der Leistungsnachweis auch erst einige Monate später für vergangene Monate - somit muss dort zwingend eine Zahl stehen und kein Datum
jensgebken
jensgebken 24.01.2024 aktualisiert um 13:26:49 Uhr
Goto Top
@blackman

und das Jahr
WHERE ((Month(Now())-[Monat]>3));

@em-pie - ich habe oben die Felder erklärt
Blackmann
Blackmann 24.01.2024 aktualisiert um 13:55:22 Uhr
Goto Top
SELECT tbl_Betreuer.id_Nachname_Vorname, tbl_Leistungsnachweis.Monat, tbl_Leistungsnachweis.Jahr, tbl_Leistungsnachweis.Stunden, DateDiff('m',Now(),[Monat]) AS MonDif  
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE (((DateDiff('m',Now(),[Monat]))>3));  

Ggfls musst Du die Argumente noch anpassen/tauschen, habe jetzt hier keine Realdaten da.
Aber die Funktion sollte klappen... auf jeden Fall testen, was bleibt auch übrig :>))

BG BM

PS: Anstelle von [Monat] musst Du eventuell Dein Datum aus den Werten in der Tabelle wieder zusammenbasteln,
also einen Datums wert erzeugen ...
jensgebken
jensgebken 24.01.2024 um 14:01:21 Uhr
Goto Top
meine nur mit dem jahr - würdest du es dann so bauen jahr & monat - oder wie meinst du es
em-pie
em-pie 24.01.2024 um 14:07:31 Uhr
Goto Top
Ich kann kein Kalenderdatum nehmen, weil im Leistungsnachweis immer der Monat gemeint ist, in dem gearbeitet wurde
und was hindert dich daran, dann einfach stumpf 01.03.2024 ind das Feld zu setzen, wenn die LEistungsperiode März 2024 gewesen ist?

meine nur mit dem jahr - würdest du es dann so bauen jahr & monat - oder wie meinst du es
Ja, du kannst die einen String zusammen setzen CONCAT('01.', MONAT, '.', JAHR) und das in ein Datum konvertieren:
cDate(Format(CONCAT('01.', MONAT, '.', JAHR),"ddd.MM.yyyy"))
und damit kannst du dann rechnen
Blackmann
Blackmann 24.01.2024 aktualisiert um 14:29:36 Uhr
Goto Top
PS: Anstelle von [Monat] musst Du eventuell Dein Datum aus den Werten in der Tabelle wieder zusammenbasteln,
also einen Datums wert erzeugen ...

DatSerial setzt ein Datum aus Werten Deiner Tabelle wieder zusammen ... Testen, ich mache das hier als Trockenübung ... :>))

SELECT tbl_Betreuer.id_Nachname_Vorname
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS MonDif;  


BG BM
jensgebken
jensgebken 24.01.2024 aktualisiert um 14:43:44 Uhr
Goto Top
@em-pie - access kennt concat nicht - hast du noch eine andere idee

wenn ich es so mache bekomme ich eine Meldung bzgl. Anzahl an Argumenten

cDate(Format('01.'& MONAT & '.' & JAHR),"ddd.MM.yyyy") as neu  
jensgebken
jensgebken 24.01.2024 um 14:52:30 Uhr
Goto Top
hier bekomme ich fehlenden operator

SELECT tbl_Betreuer.id_Nachname_Vorname
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS MonDif;    
em-pie
em-pie 24.01.2024 aktualisiert um 14:58:09 Uhr
Goto Top
Zitat von @jensgebken:

@em-pie - access kennt concat nicht - hast du noch eine andere idee
OK. Habe kein Access hier, aber du hast das Prinzip ja adaptieren können face-smile
wenn ich es so mache bekomme ich eine Meldung bzgl. Anzahl an Argumenten
cDate(Format('01.'& MONAT & '.' & JAHR),"ddd.MM.yyyy") as neu  
Du hast meinen Fehler mitkopiert face-big-smile

Versuch mal
cDate(Format('01.' & MONAT & '.' & JAHR),"dd.MM.yyyy") as neu  
dot ist ein d weniger, im Format.

Alternativ mal
cDate(Format('01/' & MONAT & '/' & JAHR),"dd/MM/yyyy") as neu  
oder
cDate(Format('"' & '01.' & MONAT & '.' & JAHR & '"'),"dd.MM.yyyy") as neu  
Blackmann
Blackmann 24.01.2024 aktualisiert um 14:58:34 Uhr
Goto Top
Jaaaa ... da war was falsch ....

SELECT tbl_Betreuer.id_Nachname_Vorname
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))<3));  
jensgebken
jensgebken 24.01.2024 aktualisiert um 15:03:45 Uhr
Goto Top
SELECT tbl_Betreuer.Nachname, tbl_Leistungsnachweis.Monat as Monat, tbl_Leistungsnachweis.Jahr as Jahr
FROM tbl_Betreuer, tbl_Leistungsnachweis
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))<3));     

Datentypenkonflikt
Blackmann
Blackmann 24.01.2024 aktualisiert um 15:24:34 Uhr
Goto Top
Siehe Postfach ... kannst ja mal die Datenbanken vergleichen!

N'8 BM
Blackmann
Blackmann 24.01.2024 um 15:36:12 Uhr
Goto Top
Aktualisierung:

SELECT tbl_Betreuer.id_Nachname_Vorname, DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS Ausdr1  
FROM tbl_Leistungsnachweis INNER JOIN tbl_Betreuer ON tbl_Leistungsnachweis.id_Betreuer = tbl_Betreuer.ID
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))>=-3));  
jensgebken
jensgebken 24.01.2024 um 16:01:07 Uhr
Goto Top
Datentypenkonflikt in Kriterienausdruck
em-pie
em-pie 24.01.2024 um 16:21:35 Uhr
Goto Top
Zitat von @jensgebken:

Datentypenkonflikt in Kriterienausdruck

Dann Drösel es auf:

SELECT 
  p.id_Nachname_Vorname
  , Now() as CurDate
  , DateSerial(lnw.Jahr, lnw.Monat, 1) as LeistDat
FROM tbl_Leistungsnachweis as lnw
INNER JOIN tbl_Betreuer as p ON lnw.id_Betreuer = p.ID
WHERE lnw.id = 4711

Kommt es immernoch zu einem Fehler, musst du dir Now() bzw. DateSerial anschauen
Danach prüfst du die Kombination beider mittels DateDiff: , DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) as Delta
Kommt es zu keinem Fehler, schaue, was mit dem DateDiff() passiert.
jensgebken
jensgebken 24.01.2024 um 16:48:33 Uhr
Goto Top
hast Recht - LeistDat ergibt #Fehler
em-pie
em-pie 24.01.2024 um 17:18:27 Uhr
Goto Top
Zitat von @jensgebken:

hast Recht - LeistDat ergibt #Fehler

Monat und Jahr sind aber gefüllt?
SELECT 
  p.id_Nachname_Vorname
  , lnw.Jahr
  , lnw.Monat
  , Now() as CurDate
  , DateSerial(lnw.Jahr, lnw.Monat, 1) as LeistDat
FROM tbl_Leistungsnachweis as lnw
INNER JOIN tbl_Betreuer as p ON lnw.id_Betreuer = p.ID
WHERE lnw.id = 4711
jensgebken
jensgebken 25.01.2024 um 08:29:55 Uhr
Goto Top
jetzt ist die Ausgabe richtig - Danke - wie würdest du es denn jetzt machen, dass ich nur die Betreuer angezeigt bekomme, die keine Leistungsnachweise für die letzten drei Monate eingereicht haben
jensgebken
jensgebken 25.01.2024 aktualisiert um 10:02:16 Uhr
Goto Top
... ist vermutlich super trickig oder

weil man müsste ja zuerst ermitteln, welcher letzte Monat eines Betreuers der letzte ist für den er einen Leistungsnachweis abgegeben hat, um dann ermitteln zu können, ob dieser mindestens 3 Monate her ist
em-pie
em-pie 25.01.2024 um 10:06:31 Uhr
Goto Top
Zitat von @jensgebken:

... ist vermutlich super trickig oder

weil müsste ja zuerst ermitteln, welcher letzte Monat eines Betreuers der letzte ist um dann ermitteln zu können ob dieser mindestens 3 Monate her ist

Nöö.
Folgendes ungetestet:
SELECT 
  p.id_Nachname_Vorname
  , lnw.Jahr
  , lnw.Monat
  , Now() as CurDate
  , DateSerial(lnw.Jahr, lnw.Monat, 1) as LeistDat
FROM tbl_Leistungsnachweis as lnw
INNER JOIN tbl_Betreuer as p ON lnw.id_Betreuer = p.ID
WHERE lnw.id not in (
    SELECT ID 
    FROM tbl_Leistungsnachweis
    WHERE DateDiff("m", Now(), DateSerial(lnw.Jahr, lnw.Monat, 1), vbMonday, 2) <= 3  
    GROUP by ID)

Mit dem Subselect in der Where-Bedingung holst du dir alle Betreuer, die in den letzten drei Monaten Leistungen erbracht haben und gruppierst das Ergebnis nach der Betreier-ID. Die dort nicht gelistet sind, nutzt du dann für die eigentliche Where-Bedingung..

Teste aber erst, ob das Datediff() die richtigen Datensätze erwischt, kann auch sein, dass "3 Monate" erst angezeigt wird, wenn ganze Monate (also ca. 90 Tage) erreicht wurden...
jensgebken
jensgebken 25.01.2024 um 10:10:19 Uhr
Goto Top
vbMonday wird nicht erkannt
em-pie
em-pie 25.01.2024 um 10:32:55 Uhr
Goto Top
Zitat von @jensgebken:

vbMonday wird nicht erkannt

dann Trage eine eine 2 ein. Steht doch Alles in den Hilfen zu den Funktionen.
Hast du dir mal im WWW die Funktionsbeschreibung(en) angeschaut?
jensgebken
jensgebken 25.01.2024 um 11:05:19 Uhr
Goto Top
warum nimmst du den Montag?
em-pie
em-pie 25.01.2024 um 12:03:57 Uhr
Goto Top
Zitat von @jensgebken:

warum nimmst du den Montag?

Weil hier in NRW die Woche nicht erst am Mittwoch (oder am Sonntag) beginnt.
Und die KW01 eines Jahres in DE mit der ersten 4Tage Woche beginnt.
Das kannst du auch weglassen, da du ja nicht mit Wochen oder Tagen arbeitest.
jensgebken
jensgebken 25.01.2024 um 15:01:49 Uhr
Goto Top
Lieben dank für Deine Hilfe - aber bekomme es einfach nicht hin - verstehe die Idee die du umsetzen möchtest - aber es geht bei mir einfach nicht
em-pie
em-pie 25.01.2024 um 17:34:00 Uhr
Goto Top
aber bekomme es einfach nicht hin - verstehe die Idee die du umsetzen möchtest - aber es geht bei mir einfach nicht
ohne eine Fehlermeldung können wir dir hier auch nicht helfen....

Du musst zwingend!!!!!! Fehlermeldungen hier posten.
jensgebken
jensgebken 25.01.2024 um 17:44:19 Uhr
Goto Top
Anbei habe ich eine Testdb - darin siehst du, dass das Ergenis der Abfrage nicht passt

https://we.tl/t-hSFINeuNdB
Blackmann
Blackmann 25.01.2024 um 23:49:25 Uhr
Goto Top
Mal in ein VM geöffnet:

pry_Nachweis --> normale Liste alle Deiner verknüpften Daten, ohne Filterung, also Übersicht
pry_Suchanfrage -->wie kommst Du denn hier auf einmal auf die Tabellen mit Name 'p' und 'lnw'

Auch hier sollten Deine Basitabellen: tbl_Betreuer; tbl_Leistungsnachweis; tbl_Patient sein,mit denen musst Du arbeiten.

Schaue Dir mal die Abfrage in meiner DB an, es ist ja nur eine da, die Funktioniert meiner Meinung nach, den WHERE Teil musst Du verstehen: Es werden alle angezeigt mit 0, -1, -2, -3, also aktuelle Monat und 3 Monate davor.

SELECT tbl_Betreuer.id_Nachname_Vorname, DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS Differenzmonate  
FROM tbl_Betreuer INNER JOIN tbl_Leistungsnachweis ON tbl_Betreuer.ID = tbl_Leistungsnachweis.id_Betreuer
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))>=-3));  
em-pie
em-pie 26.01.2024 um 06:55:15 Uhr
Goto Top
wie kommst Du denn hier auf einmal auf die Tabellen mit Name 'p' und 'lnw'
Vermutlich hat er oben mein Query „blind“ kopiert. Habe dort ja mit entsprechenden Alias gearbeitet…
Wenn er das nicht adaptiert hat…


@jensgebken
Hab mir die mdb nicht angeschaut, da kein Access zur Hand…
Stell hier doch Screenshots (geschwärzt) ein…
Und ganz wichtig: lerne komplexe Probleme zu zergliedern. So schwer ist das doch nicht…
Blackmann
Blackmann 06.02.2024 aktualisiert um 19:31:33 Uhr
Goto Top
1. Natürlich musst Du in Deiner Tabelle die Felddatentypen sauber implementieren --> siehe meine Beispieltabelle.
Das scheint bei Dir noch nicht der Fall zu sein ... Zahl != Text ... das kann man so einfach nicht vergleichen...

2. Mit
SELECT tbl_Betreuer.id_Nachname_Vorname, DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS Differenzmonate  
FROM tbl_Betreuer INNER JOIN tbl_Leistungsnachweis ON tbl_Betreuer.ID = tbl_Leistungsnachweis.id_Betreuer
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))>=-3));  
bekomme ich alle IN den letzten 3 Monaten

SELECT tbl_Betreuer.id_Nachname_Vorname, DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)) AS Differenzmonate  
FROM tbl_Betreuer INNER JOIN tbl_Leistungsnachweis ON tbl_Betreuer.ID = tbl_Leistungsnachweis.id_Betreuer
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))<-3));  
bekomme ich alle VOR den letzten 3 Monaten

Schau dir den Unterschied an, Du findet ihn im WHERE-Abschnitt

N'8 BM
jensgebken
jensgebken 10.02.2024 um 13:33:18 Uhr
Goto Top
Kann man das vielleicht noch gruppieren bzw. das nur der letzte Monat des Betreuers angezeigt wird
em-pie
em-pie 10.02.2024 um 13:53:36 Uhr
Goto Top
Zitat von @jensgebken:

Kann man das vielleicht noch gruppieren bzw. das nur der letzte Monat des Betreuers angezeigt wird

Ja, tausche 3 durch 1

oder arbeite mir GROUP BY und im SELECT-Teil mit MAX()
jensgebken
jensgebken 10.02.2024 um 14:06:54 Uhr
Goto Top
... das mit dem Tausch hat nicht geklappt - schaue mir nun das mit group by an
jensgebken
jensgebken 10.02.2024 um 15:11:23 Uhr
Goto Top
mit max meinst du so?

SELECT tbl_Betreuer.Nachname, max(DateDiff('m',Now(),DateSerial([Jahr],[Monat],1))) AS Differenzmonate  
FROM tbl_Betreuer INNER JOIN tbl_Leistungsnachweis ON tbl_Betreuer.ID = tbl_Leistungsnachweis.id_Betreuer
WHERE (((DateDiff('m',Now(),DateSerial([Jahr],[Monat],1)))<-3));  

dann bekomme ich -- in der abfrage ist der angegebene Ausdruck Nachname nicht als bestandteil einer aggregatsfunktion enthalten
jensgebken
jensgebken 10.02.2024 um 15:15:05 Uhr
Goto Top
ah sorry group by fehlte - nun klappt es - danke