【问题标题】:Where clause between dates with pivot table without losing data带有数据透视表的日期之间的 Where 子句不会丢失数据
【发布时间】:2017-08-02 16:49:21
【问题描述】:

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

任务

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

非常感谢

【问题讨论】:

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


    【解决方案1】:

    问题在于,尽管您离开了 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)
    

    注意,我已将 BETWEEN 更改为开放式范围,原因在本文中列出:What do BETWEEN and the devil have in common?

    【讨论】:

    • 太好了,成功了,谢谢!没想到我可以走得太远!
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 2015-01-03
      • 1970-01-01
      • 2015-11-20
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多