查询未返回正确的值

时间:2014-07-28 18:36:21

标签: sql sql-server

我在下面的查询是一个庞然大物:

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)

返回如下结果:

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

效果很好..但现在我想限制项目返回的小时数。因此,在查询中,您会看到一条注释掉JOIN Projects PR ON te.HarvestProjectId = PR.Id的行。当我添加那些代码时,它会完全弄乱计算并且不返回任何内容。像这样:

StartDate   EndDate Completes   Hours   HoursPerRecruit RecruitsPerHour
2014-07-10 00:00:00.0000000 +00:00  2014-07-10  6   NULL    NULL    NULL

我错过的是使HoursPerRecruit和RecruitsPerHour为空?我似乎无法弄明白。

2 个答案:

答案 0 :(得分:1)

我知道这不是一个完整的答案,但我不能在评论中格式化代码。

查看这段代码,并使用参数的某个有效值执行它:

    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

然后取消评论评论行。它没有返回任何行吗?我猜这将是基于你描述的情况。

如果是这样,那么看看结果:

SELECT * FROM Projects

并查看是否可以找出为什么Projects表中没有行加入TimeEntries表。也许你加入了错误的列,或者数据格式不匹配。

答案 1 :(得分:1)

如果您尝试限制结果,则条件应位于注释掉的联接下面的Where子句中。如果您的Project.ID直接链接到TimeEntries.HarvestProjectId,没有其他条件,您应该可以更改该行

WHERE u.Id = @UserId

到:

WHERE u.Id = @UserId and te.HarvestProjectId=@ProjectID