Question

So banging my head against the wall and can't see the wood for the trees...

I've got two tables; 1. ID field, start date and end date columns. 2. Date and Workday columns.

I just need to be able to count the days between the two for each row using this dates on the second calendar. Googl'ing had found plenty of examples without the dates table and plenty of examples where its just based on 1 start and end date.

Table_1 - Contains an entry for every id

id          start_date      end_date
123         01/01/2013     03/01/2013
456         02/01/2013     08/01/2013
789         06/01/2013     07/01/2013

Table_2 - Contains an entry for everyday

  e_day         workday
01/01/2013         1
02/01/2013         0
03/01/2013         1
04/01/2013         1
05/01/2013         0
06/01/2013         1
07/01/2013         0
08/01/2013         0

Results id start_date end_date days_between 123 01/01/2013 03/01/2013 2 456 02/01/2013 08/01/2013 3 789 06/01/2013 07/01/2013 1

I can find out the value for 1 id;

SELECT COUNT(workday) FROM table_2
WHERE workday = 1 AND cal_day >= '01/01/2013' 
AND cal_day <= '03/01/2013';

Just not sure how to put this logic in to table_1. IE (Clearly not correct)

SELECT 
table_1.id, 
table_1.start_date, 
table_1.end_date,
(COUNT(table_2.workday) FROM table_2 WHERE table_2.workday = 1
AND table_2.e_day >= table_1.start_date 
AND table_2.e_day <= table_2.end_date) AS days_between
FROM table_1

Code to generate bodged example tables;

CREATE TABLE #table_1(id INT, start_date SMALLDATETIME, end_date SMALLDATETIME);
CREATE TABLE #table_2(e_day SMALLDATETIME, workday BIT);

INSERT #table_1 VALUES (123,'01/01/2013','03/01/2013')
INSERT #table_1 VALUES (456,'02/01/2013','08/01/2013')
INSERT #table_1 VALUES (789,'06/01/2013','07/01/2013')

INSERT #table_2 VALUES ('01/01/2013',1)
INSERT #table_2 VALUES ('02/01/2013',0)
INSERT #table_2 VALUES ('03/01/2013',1)
INSERT #table_2 VALUES ('04/01/2013',1)
INSERT #table_2 VALUES ('05/01/2013',0)
INSERT #table_2 VALUES ('06/01/2013',1)
INSERT #table_2 VALUES ('07/01/2013',0)
INSERT #table_2 VALUES ('08/01/2013',0)

SELECT * FROM #table_1
SELECT * FROM #table_2

Code to remove tables;

DROP TABLE #table_1 DROP TABLE #table_2;

Thanks all for you help in advance :)

Was it helpful?

Solution

Try this:

select a.id,a.start_date,a.end_date,sum(cast(workday as tinyint)) as NumWorkDays,
           count(*) as Total_days
from idTable a
join workdaytable b on b.eday between a.start_date and a.end_Date
group by a.id,a.start_date,a.end_date

To visualize what is happening

select a.id,a.start_date,a.end_date   
where id=123

id    start_date   end_date
123   1/1/2013     3/1/2013

returns one row for id=123

Now, when we do the join, we add e_day and the workday flag columns AND we add one row for each e_day in the second table

id    start_date   end_date    e_day   work_day
123   1/1/2013     3/1/2013    1/1/2013       0
123   1/1/2013     3/1/2013    1/2/2013       1
123   1/1/2013     3/1/2013    1/3/2013       1
etc.

Now we had a big "table" with 5 columns and one row for each day in the second table that falls between 1/1/2013 and 3/1/2013. The Sum operation simply adds all of the work_day flag from the "table" we created by the join. If you run the query without the JOIN (and remove the sum and count), you can see the "table" that gets created...

Hope this helps a bit...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top