简体   繁体   中英

Finding Consecutive and single instance dates, between two dates, in Access(SQL)

Morning all,

I want to know every instance of absence, where an instance is any single day or set of consecutive days, between two date points. I had extensive help on this in my original question and have working code for everything except the "Between two dates" part. I am hoping someone can help me to add the "between two dates" element to the working code.

Example question:
How many instances, and total days, of absence has everyone had between 03/01/16 and 19/01/16?

Sample data:

|IDRef  |RecordDate  |Racf  |Type  |LengthOfAbsence 
|1788  |04-Jan-16  |Bob  |Sickness |420
|1789  |04-Jan-16  |Jill  |Sickness |420 
|1790  |05-Jan-16  |Bob  |Sickness |420 
|1791  |17-Jan-16  |Jill|Sickness |420  
|1792  |18-Jan-16  |Bob  |Sickness |420   

Expected output:

| Racf  |Total Days  |Instances
|Bob  | 3  |2  
|Jill  |2  |2

Working code:

SELECT Absence.Racf, Count(Absence.RecordDate) AS CountOfRecordDate
FROM Absence LEFT JOIN (select Racf, [RecordDate]+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate2 from Absence) AS t2 ON (Absence.RecordDate = t2.RecordDate2) AND (Absence.Racf = t2.Racf)
WHERE (((t2.RecordDate2) Is Null))
GROUP BY Absence.Racf;

My most recent attempt to amend it to only look between two dates (this doesn't cause an error but does return unexpected/incorrect values):

Sql = "SELECT Absence.Racf, Count(Absence.RecordDate) AS CountOfRecordDate "
Sql = Sql & "FROM Absence LEFT JOIN (select Racf, [RecordDate]+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate2 from Absence where [RecordDate] BETWEEN #" & sFromDate & "# AND #" & sToDate & "#) AS t2 ON (Absence.RecordDate = t2.RecordDate2) AND (Absence.Racf = t2.Racf) "
Sql = Sql & "WHERE (((t2.RecordDate2) Is Null)) AND [t2.RecordDate2] BETWEEN #" & sFromDate & "# AND #" & sToDate & "# "
Sql = Sql & "GROUP BY Absence.Racf;"

Original question here: Count instances of consecutive dates for associated name (VBA, SQL)

Any help with this last step would be greatly appreciated, an explanation of why it works wouldn't hurt, either, as I have no idea!

Here is my new working code that I have tested in Access but not yet in a macro called from Excel

SELECT Absence.Racf, Count(Absence.RecordDate) AS CountOfRecordDate, Absence.RecordDate
FROM Absence LEFT JOIN [select Racf, [RecordDate]+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate2 from Absence]. AS t2 ON (Absence.Racf = t2.Racf) AND (Absence.RecordDate = t2.RecordDate2)
WHERE (((t2.RecordDate2) Is Null))
GROUP BY Absence.Racf, Absence.RecordDate
HAVING (((Absence.RecordDate)>#1/1/2016# And (Absence.RecordDate)<#10/11/2016#));

The reason a date range didn't work in the WHERE clause was that the date here is always NULL so you never get any records.

You could equally well use a BETWEEN statement instead of > and <.

I'm sorry this isn't the neat solution you were looking for, but this is getting beyond what you can easily do in a single query in Access. The output looks like this

在此处输入图片说明

What I suggest you do (if you imagine this for several users) is to use a pivot table to summarise the results for each user.

But you may also try this

SQL = "select racf, count(racf) AS Instances from ("
SQL = SQL & "SELECT Absence.Racf, Count(Absence.RecordDate) AS CountOfRecordDate,Absence.RecordDate"
SQL = SQL & " FROM (Absence LEFT JOIN (select Racf, RecordDate+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate1 from Absence) AS t1 ON (Absence.RecordDate = t1.RecordDate1) AND (Absence.Racf = t1.Racf))"
SQL = SQL & " WHERE ((t1.RecordDate1) Is Null) "
SQL = SQL & " GROUP BY Absence.Racf,Absence.RecordDate"
SQL = SQL & " HAVING (((Absence.RecordDate)>#1/1/2016# And (Absence.RecordDate)<#10/11/2016#))"
SQL = SQL & ") AS T0 GROUP BY RACF"

EDIT

I'm sure on reflection that although correct, this can be simplified because the inner GROUP BY isn't serving any useful purpose - the HAVING clause should be brought outside T0 as a WHERE clause.

It should look like this

SQL = "select racf, count(racf) AS Instances from ("
SQL = SQL & "SELECT Absence.Racf, Absence.RecordDate"
SQL = SQL & " FROM (Absence LEFT JOIN (select Racf, RecordDate+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate1 from Absence) AS t1 ON (Absence.RecordDate = t1.RecordDate1) AND (Absence.Racf = t1.Racf))"
SQL = SQL & " WHERE ((t1.RecordDate1) Is Null) "
SQL = SQL & ") AS T0 WHERE (((RecordDate)>#1/1/2016# And (RecordDate)<#10/11/2016#))"
SQL = SQL & "GROUP BY RACF"

EDIT

Have now tested this and it does work but a date like #10/11/2016# is ambiguous - although my locale is UK it appeared to be interpreted as October 11th 2016.

Suggest using instead

Datevalue(""10 November 2016"")

where quotes have to be doubled up because they appear in a quoted string.

Thanks to Tom's answers I finally got there.

To retrieve instances of individual or consecutive dates, within a date range, here is what worked:

  • Created a new table to hold the dates required.
  • Run a query held in Access, from Excel to append the required records, between the date points, in to the new table.
  • Run a Select query from Excel to return the instances, excluding Sundays.

To run the query from Excel (db already defined as OpenDatabase):

db.QueryDef.Execute

Append query:

    INSERT INTO AbsenceInstances ( Racf, RecordDate )
    SELECT Absence.Racf, Absence.RecordDate
    FROM Absence
    WHERE ((Absence.RecordDate)>=#01/01/2017# And (Absence.RecordDate)<=#28/03/2017#);

Select Query:

Sql = "SELECT AbsenceInstances.Racf, Count(AbsenceInstances.RecordDate) AS CountOfRecordDate"
Sql = Sql & " FROM AbsenceInstances LEFT JOIN (select Racf, [RecordDate]+IIf(Weekday([RecordDate],7)=1,2,1) as RecordDate2 from AbsenceInstances) AS t2 ON (AbsenceInstances.RecordDate = t2.RecordDate2) AND (AbsenceInstances.Racf = t2.Racf)"
Sql = Sql & " WHERE (((t2.RecordDate2) Is Null))"
Sql = Sql & " GROUP BY AbsenceInstances.Racf;"

Can't thank Tom enough for his help. I hope this summation is useful for anyone else in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM