Where 日期之间的子句与 pivot table 不丢失数据

Where clause between dates with pivot table without losing data

我正在尝试根据用户在某些表中完成的工作显示一些数据

任务

TaskID       TaskTitle
----------------------
1            Job 1
2            Job 2
3            Job 3

工作Table

JobID        AssignedTo
----------------------------
1            guid1
2            guid2
3            guid3

用户Table

UsersGuid    UserName
------------------
guid1        Username1
guid2        Username2
guid3        Username3

而我要显示的是下面这样的东西

Task   UserName1     UserName2     UserName3
Task1  0             0             0
Task2  0             97            4
Task3  0             6             0
Task4  2             40            55

我有以下代码,但我遇到的问题是我希望它仍然显示任务名称,即使从未对其进行过任何操作,但如果没有找到任何值,它就不会显示它。

create table #TempTable
        (
            JobID int,
            TaskID int, 
            TaskTitle varchar(max),
            UserName varchar(max)
        )

INSERT INTO #TempTable

    select
    Job.JobID,
    Job.TaskID,
    tasks.TaskTitle,
    users.UserName as AssignedName

    from TaskLookups tasks

    left join Jobs job on
    tasks.TaskID = job.TaskID

    left join Users users on
    job.TaskAssignedTo = users.UserID

    WHERE
    (job.JobDateTime BETWEEN CONVERT(DATETIME, '2016-12-01 00:00:00', 102) AND CONVERT(DATETIME, '2017-07-01 23:59:00', 102))

declare @query as nvarchar(max),
@cols as nvarchar(max)

    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(UserName) 
                    from StaffUsers
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 
    '
    Select * From #TempTable 
    pivot ( count(JobID) For UserName in(' + @cols + ')) as Result order by TaskTitle
    '
exec sp_executesql @query
DROP TABLE #TempTable

非常感谢

添加 UNION ALL 和 SELECT 未分配任务列表(其中 JobId 为 NULL)并将它们的用户名设为 0。

问题是,尽管您离开加入 Jobs,然后您在 WHERE 子句中使用 job.JobDateTime

WHERE
(job.JobDateTime BETWEEN CONVERT(DATETIME, '2016-12-01 00:00:00', 102) 
            AND CONVERT(DATETIME, '2017-07-01 23:59:00', 102))

任何在给定日期时间没有工作的任务对于 job.JobDateTime 的值为 NULL,并且 NULL 不在 2016 年 12 月 1 日和 2017 年 7 月 1 日之间,因此删除整行,从而删除任务。有效地使您的左连接成为内部连接。

您应该将谓词移动到连接条件:

LEFT JOIN Jobs job 
    ON tasks.TaskID = job.TaskID 
    AND job.JobDateTime >= CONVERT(DATETIME, '2016-12-01', 102) 
    AND job.JobDateTime < CONVERT(DATETIME, '2017-07-02', 102)

N.B 我已将 BETWEEN 更改为开放式范围,原因如本文所述:What do BETWEEN and the devil have in common?.