Tuesday, 28 August 2018

The query does not return the appropriate values

I have the query below which is a mammoth:

DECLARE @Start Date, @End Date, @DaySpan int, @UserId int, @ProjectId int
SET @Start = '7/08/2014 12:00 AM -05:00';
SET @End = '7/27/2014 12:00 AM -05:00';
SET @DaySpan = 1;
SET @UserId = 102;
SET @ProjectId = 2065;

WITH T(StartDate, EndDate)
    AS (
        SELECT @Start StartDate, DATEADD(DAY, @DaySpan - 1, @Start) EndDate
        UNION ALL
        SELECT DATEADD(DAY, 1, EndDate) StartDate, DATEADD(DAY, @DaySpan, EndDate) FROM T WHERE DATEADD(DAY, @DaySpan, EndDate) <= @End
    )
    SELECT convert(datetimeoffset, T.StartDate) StartDate, T.EndDate, ISNULL(Completes, 0) Completes, SUM(h.Hours) Hours, SUM(h.Hours) / NULLIF(Completes, 0) HoursPerRecruit,
    ISNULL(Completes, 0) / NULLIF(SUM(h.Hours), 0) RecruitsPerHour
    FROM T LEFT JOIN (
        SELECT StartDate, EndDate, COUNT(r.Id) Completes
        FROM Respondents r JOIN T st ON r.RecruitedOn >= st.StartDate AND r.RecruitedOn < DATEADD(day, 1, st.EndDate)
        WHERE r.RecruitingStatus = 7
        AND RecruitedBy = @UserId
        AND r.ProjectId = @ProjectId -- **REMOVE Line If you just want by User**
        GROUP BY st.StartDate, st.EndDate
    ) c ON T.StartDate = c.StartDate AND T.EndDate = c.EndDate
        LEFT JOIN (
            SELECT st.StartDate, st.EndDate, SUM(Hours) Hours
            FROM T st JOIN TimeEntries te ON te.Date >= CONVERT(DATE, st.StartDate) AND te.Date < DATEADD(day, DATEDIFF(day,0,CONVERT(DATE, st.EndDate)),1)
                JOIN Users u ON te.HarvestUserId = u.HarvestId
                --JOIN Projects PR ON te.HarvestProjectId = PR.Id
                WHERE u.Id = @UserId
                GROUP BY st.StartDate, st.EndDate
            ) h ON T.StartDate = h.StartDate AND T.EndDate = h.EndDate
    GROUP BY T.StartDate, T.EndDate, Completes
    ORDER BY T.StartDate
    OPTION(MAXRECURSION 32767)

It returns results like below:
StartDate   EndDate Completes   Hours   HoursPerRecruit RecruitsPerHour
2014-07-10 00:00:00.0000000 +00:00  2014-07-10  6   3.00    0.500000    2.00000000000000000000000000

It works great.. But now I want to limit the hours returned by project. So in the query you will see a line that is commented out that JOIN Projects PR ON te.HarvestProjectId = PR.Id. When I add that bit of code it completely messes up the calculations and returns nothing. Like so:
StartDate   EndDate Completes   Hours   HoursPerRecruit RecruitsPerHour
2014-07-10 00:00:00.0000000 +00:00  2014-07-10  6   NULL    NULL    NULL

What am I missing that is is making the HoursPerRecruit and RecruitsPerHour be null? I can't seem to figure it out.

I know this isn't a complete answer, but I can't format code in a comment.
Look at just this bit of code, and execute it with some valid value for the parameter:
    SELECT st.StartDate, st.EndDate, SUM(Hours) Hours
    FROM T st JOIN TimeEntries te ON te.Date >= CONVERT(DATE, st.StartDate) AND te.Date < DATEADD(day, DATEDIFF(day,0,CONVERT(DATE, st.EndDate)),1)
        JOIN Users u ON te.HarvestUserId = u.HarvestId
        --JOIN Projects PR ON te.HarvestProjectId = PR.Id
        WHERE u.Id = @UserId
        GROUP BY st.StartDate, st.EndDate

Then un-comment the commented line. Does it return no rows? I'm guessing that will be the case based on what you describe.
If so, then look at the results of this:
SELECT * FROM Projects

and see if you can figure out why no rows from the Projects table are joining to the TimeEntries table. Maybe you're joining on the wrong columns, or there's a mis-match in the data format.

0 comments:

Post a Comment