Reputation: 21
My query seems simple and maybe im over thinking it. Consider 2 tables: Client A and Service B. The clients table has 2 dates, Service Start Date & Service End Date. Now, our KPI is we should have provided atleast 1 service to each client that has been active with us for more than 15 days in that month. This is a monthly KPI. My interface lets you pick a 3 month or 6 month period for reporting and the report needed is Count of Client serviced by Month. This will be grouped by month and the Region they are in.
Client Table A
C_ID | Name | SrvStDt | SrvEndDt | ServManager | Region
1 | ABCD | 1 Jan 16 | 10 Mar 16 | AAAAAA | North
2 | EDFG | 1 Feb 16 | 15 Aug 16 | BBBBBB | South
3 | YTHG | 1 Mar 16 | 1 Jul 16 | CCCCCC | East
4 | WEFG | 21 Apr 16| 15 May 16 | DDDDDD | West
5 | POIU | 18 May 16| 15 Jul 16 | AAAAAA | North
6 | QWER | 30 Jun 16| -- | BBBBBB | South
7 | CVBH | 21 Jul 16| -- | CCCCCC | East
8 | ASDR | 1 Aug 16 | -- | DDDDDD | West
9 | LKJU | 15 Jan 16| 15 Jul 16 | AAAAAA | North
10 | MNBU | 15 Mar 16| 15 Jul 16 | BBBBBB | South
Notes : No end date signifies the client is still active
Service Table B
ID | SrvDAte
1 | 15 Jan 16
1 | 12 Feb 16
1 | 01 Mar 16
1 | 10 Mar 16
2 | 15 Feb 16
2 | 15 Mar 16
2 | 31 Mar 16
2 | 15 Apr 16
2 | 15 May 16
2 | 15 Jul 16
2 | 15 Aug 16
3 | 21 Mar 16
3 | 23 Mar 16
3 | 23 Apr 16
3 | 23 May 16
4 | 29 Apr 16
5 | 23 May 16
6 | 12 Jul 16
7 | 23 Jul 16
9 | 23 Mar 16
9 | 23 Apr 16
9 | 23 May 16
10 | 19 Mar 16
10 | 19 Apr 16
10 | 19 May 16
10 | 19 Jun 16
For a report from 1 April - 31 Jul the Result im after will look something like this:
Region | Month | Total Active | Total Serviced
North | Apr-16 | XXXX | XXXX
North | May-16 | XXXX | XXXX
North | Jun-16 | XXXX | XXXX
North | Jul-16 | XXXX | XXXX
South | Apr-16 | XXXX | XXXX
South | May-16 | XXXX | XXXX
South | Jun-16 | XXXX | XXXX
South | Jul-16 | XXXX | XXXX
East | Apr-16 | XXXX | XXXX
East | May-16 | XXXX | XXXX
East | Jun-16 | XXXX | XXXX
East | Jul-16 | XXXX | XXXX
West | Apr-16 | XXXX | XXXX
West | May-16 | XXXX | XXXX
West | Jun-16 | XXXX | XXXX
West | Jul-16 | XXXX | XXXX
I'm struggling with how to identify clients that are active for at least 15 days in a month for all of the reporting period. I can put a between clause for the whole period, e.g., 1 Apr - 1 Jul, but how do I break it into months and evaluate for each month?
I'm using MS Access VBA & SQL queries. I would like an SQL query that gives me this result set.
Upvotes: 0
Views: 46
Reputation: 123409
I'm struggling with how to identify clients that are active for at least 15 days in a month for all of the reporting period. I can put a between clause for the whole period, e.g., 1 Apr - 1 Jul, but how do I break it into months and evaluate for each month?
One way to derive those counts would be to use a "numbers table" that starts at zero and covers the largest possible number of days between the start date and the end date, e.g.,
[Numbers]
n
---
0
1
2
3
...
998
999
Then, for sample data
[TableA]
C_ID SrvStDt SrvEndDt
---- ---------- ----------
1 2016-01-01 2016-01-04
2 2016-02-28 2016-03-02
3 2016-08-10
the query
SELECT
C_ID,
DateAdd("d", n, SrvStDt) AS SrvDate
FROM TableA, Numbers
WHERE
DateAdd("d", n, SrvStDt) <= Nz(SrvEndDt, Date())
returns
C_ID SrvDate
---- ----------
1 2016-01-01
1 2016-01-02
1 2016-01-03
1 2016-01-04
2 2016-02-28
2 2016-02-29
2 2016-03-01
2 2016-03-02
3 2016-08-10
3 2016-08-11
3 2016-08-12
3 2016-08-13
3 2016-08-14
3 2016-08-15
and if we wrap that in an aggregation query to COUNT the dates in each Year/Month (GROUP BY)
SELECT
C_ID,
Year(SrvDate) AS SrvYear,
Month(SrvDate) AS SrvMonth,
COUNT(*) AS SrvDays
FROM
(
SELECT
C_ID,
DateAdd("d", n, SrvStDt) AS SrvDate
FROM TableA, Numbers
WHERE
DateAdd("d", n, SrvStDt) <= Nz(SrvEndDt, Date())
)
GROUP BY
C_ID,
Year(SrvDate),
Month(SrvDate)
we get
C_ID SrvYear SrvMonth SrvDays
---- ------- -------- -------
1 2016 1 4
2 2016 2 2
2 2016 3 2
3 2016 8 6
Upvotes: 1