返回的行不符合JOIN

时间:2013-12-10 15:12:08

标签: sql sql-server

表中有两种类型的行:

enter image description here

标准数据与taskId绑定并在进程中加载​​到数据库中,下面的前两行是这种类型的数据。第二种类型的数据未在过程中加载,它作为表单的一部分插入。你可以看到差异,因为第一类数据有一个taskId,而NonScrumStoryId是NULL。在第二种情况下,填充NonScrumStoryId列并且TaskId为NULL。

我有一个查询来从这个表中获取数据:

DECLARE @startDateParam DATETIME
    ,@endDateParam DATETIME
    ,@productId VARCHAR(100)
    ,@search VARCHAR(100)
    ,@userParam VARCHAR(100)
    ,@orgTeamPK VARCHAR(100)

SET @startDateParam = '2013-11-25 00:00:00'
SET @endDateParam = '2013-12-01 23:59:59'
SET @productId = '%'
SET @search = '%%'
SET @userParam = '%'
SET @orgTeamPK = '%'

SELECT '3' AS RowType
        ,DTH.EnteredBy AS Person
        ,COALESCE(PDT.[Name], APP.AppName) AS Project
        ,(
            CASE WHEN (
                        STY.KanBanProductId IS NOT NULL
                        AND STY.SprintId IS NULL
                        ) THEN 'KanBan' WHEN (
                        STY.KanBanProductId IS NULL
                        AND STY.SprintId IS NOT NULL
                        ) THEN 'Sprint' ELSE SCY.Catagory END
            ) AS ProjectType
        ,COALESCE(STY.[Number], NSS.IncidentNumber) AS StoryNumber
        ,COALESCE(STY.Title, NSS.[Description]) AS StoryTitle
        ,CONVERT(VARCHAR(20), STY.Effort) AS Effort
        ,COALESCE(TSK.[Name], '') AS Task
        ,CONVERT(VARCHAR(20), TSK.OriginalEstimateHours) AS OriginalEstimateHours
        ,SCY.Catagory AS Category
        ,NSS.IncidentNumber AS IncidentNumber
        ,APP.AppName AS ApplicationName
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 2 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS MondayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 3 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS TuesdayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 4 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS WednesdayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 5 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS ThursdayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 6 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS FridayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 7 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS SaturdayHours
        ,CAST(SUM(CASE WHEN DATEPART(dw, DTH.ActivityDate) = 1 THEN DTH.[Hours] ELSE 0 END) AS VARCHAR(20)) AS SundayHours
        ,CAST(SUM(DTH.[Hours]) AS VARCHAR(20)) AS TotalHours
        ,CAST(SUM(CASE WHEN DTH.Hours > 0 THEN DTH.[UserDifference] END) AS VARCHAR(20)) AS DifferentUsers
        ,CAST(SUM(CASE WHEN DTH.Hours > 0 THEN DTH.DoubleBookedFlag END) AS VARCHAR(20)) AS DoubleBookedFlag
        ,DTH.PointPerson AS PointPerson
    FROM DailyTaskHours DTH
    LEFT JOIN Task TSK ON DTH.TaskId = TSK.PK_Task
    LEFT JOIN Story STY ON TSK.StoryId = STY.PK_Story
    LEFT JOIN NonScrumStory NSS ON DTH.NonScrumStoryId = NSS.PK_NonScrumStory
    LEFT JOIN SupportCatagory SCY ON NSS.CatagoryId = SCY.PK_SupportCatagory
    LEFT JOIN [Application] APP ON NSS.ApplicationId = APP.PK_Application
    LEFT JOIN Sprint SPT ON STY.SprintId = SPT.PK_Sprint
    LEFT JOIN Product PDT ON STY.ProductId = PDT.PK_Product
    LEFT JOIN [User] USR ON DTH.EnteredBy = USR.DisplayName
    WHERE DTH.EnteredBy LIKE @userParam
        AND ActivityDate >= @startDateParam
        AND ActivityDate <= @endDateParam
        AND PDT.PK_Product LIKE @productId
        AND (
            (
                @orgTeamPK = '%'
                AND (
                    USR.[OrganizationalTeamId] LIKE @orgTeamPK
                    OR USR.[OrganizationalTeamId] IS NULL
                    )
                )
            OR (
                @orgTeamPK <> '%'
                AND (USR.[OrganizationalTeamId] LIKE @orgTeamPK)
                )
            AND (
                (
                    STY.Number LIKE @search
                    OR STY.Number IS NULL
                    )
                OR (
                    STY.Title LIKE @search
                    OR STY.Number IS NULL
                    )
                OR (
                    TSK.NAME LIKE @search
                    OR STY.Number IS NULL
                    )
                )
            )
    GROUP BY DTH.EnteredBy
        ,PDT.[Name]
        ,SPT.[Name]
        ,SPT.[Description]
        ,STY.[Number]
        ,STY.Title
        ,TSK.[Name]
        ,SCY.Catagory
        ,NSS.IncidentNumber
        ,APP.AppName
        ,STY.KanBanProductId
        ,STY.SprintId
        ,NSS.[Description]
        ,TSK.OriginalEstimateHours
        ,STY.Effort
        ,DTH.PointPerson
    HAVING SUM(DTH.[Hours]) > 0

我的问题是这个查询只返回来自进程的表中的行,它不返回NonScrumStory列,我需要它。

编辑:WHERE子句的一部分导致问题。

Ater调查可能与这条线有关:

AND PDT.PK_Product LIKE @productId

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

您正在使用

加入Task
LEFT JOIN Task TSK ON DTH.TaskId = TSK.PK_Task

然后使用

加入Story
LEFT JOIN Story STY ON TSK.StoryId = STY.PK_Story

然后使用

加入Product
LEFT JOIN Product PDT ON STY.ProductId = PDT.PK_Product

(注意任务 - &gt;故事 - &gt;产品依赖)

这些联接都很好,但您使用

过滤Product
AND PDT.PK_Product LIKE @productId

无论如何,这将匹配具有类似参数的产品的行,而这些行又将结果限制为具有故事的行,这限制了具有任务的行。

您可以检查@productId是否为空或等于产品。如果未指定参数,这将允许您返回所有行,或返回过滤到产品的行。

...
AND ActivityDate <= @endDateParam
AND (@productId IS NULL OR PDT.PK_Product LIKE @productId)
AND (
...

如果您需要始终过滤产品,那么您可能必须使用UNION并选择包含任务的所有行,然后选择另一行中包含NonScrumStory的所有行。