带有数据透视表的日期之间的Where子句,不会丢失数

时间:2017-08-02 16:49:21

标签: sql date pivot-table where-clause temp-tables

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

任务

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

工作表

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

用户表

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

非常感谢

2 个答案:

答案 0 :(得分:1)

问题在于,虽然您已加入Jobs,但您在job.JobDateTime子句中使用了WHERE

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

在给定日期时间内没有工作的任何任务NULL的值为job.JobDateTime,而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?

答案 1 :(得分:0)

添加UNION ALL并选择未分配的任务列表(WHERE JobId为NULL)并将用户名设置为0。