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?.
我正在尝试根据用户在某些表中完成的工作显示一些数据
任务
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?.