WHERE子句根据参数值运行不同

时间:2014-02-03 21:39:53

标签: sql-server tsql

我正在处理一个大型查询:

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

SET @userParam = 'David Tunnell (tunnelld)'
SET @startDateParam = '2014-01-27'
SET @endDateParam = '2014-02-02'
SET @orgTeamPK = '%'
SET @search = '%'
SET @productId = '%'
SET @themeParam = '%'

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
    LEFT JOIN [StoryProductTheme] SPM ON STY.PK_Story = SPM.StoryId
    LEFT JOIN [ProductTheme] PTM ON SPM.ProductThemeId = PTM.PK_ProductTheme
    WHERE DTH.EnteredBy LIKE @userParam
        AND ActivityDate >= @startDateParam
        AND ActivityDate <= @endDateParam
        AND 1 = CASE ISNUMERIC(@productId)
            WHEN 0
                THEN CASE 
                        WHEN DTH.TaskId IS NULL
                            OR PDT.PK_Product LIKE @productId
                            THEN 1
                        END
            WHEN 1
                THEN CASE 
                        WHEN DTH.TaskId IS NOT NULL
                            AND PDT.PK_Product = @productId
                            THEN 1
                        END
            END
        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.Title IS NULL
                    )
                OR (
                    TSK.NAME LIKE @search
                    OR TSK.NAME 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

我想尝试做的是添加以特定方式过滤的功能。这是我添加到WHERE子句的代码:

    AND (
        ISNUMERIC(@themeParam) = 0
        AND PTM.ThemeId LIKE @themeParam
        )
    OR (
        ISNUMERIC(@themeParam) = 1
        AND @themeParam = 6
        AND STY.KanBanProductId IS NULL
        AND STY.SprintId IS NOT NULL
        )
    OR (
        ISNUMERIC(@themeParam) = 1
        AND @themeParam <> 6
        AND PTM.ThemeId = @themeParam
        )

这是我的代码目标:

如果@themeParam = '%',我想要运行第一部分,因为ISNUMERIC(@themeParam)应评估为零。

如果@themeParam = 6,我希望第二部分运行并返回所有值STY.KanBanProductId IS NULL AND STY.SprintId IS NOT NULL

如果@themeParam <> 6,我希望第一个投放,只返回PTM.ThemeId = @themeParam

我有两个问题。所有的拳头我得到错误:

  

将varchar值'%'转换为数据类型时转换失败   中间体

我认为如果ISNUMERIC(@themeParam)未评估为1,则其余代码将无法运行,并且不会尝试将'%'与6进行比较。

我的第二个问题是,当我为@themeParam输入一个数字时,查询会运行,但似乎忽略了where子句的所有其他部分,我不明白为什么。

我做错了什么,我该如何解决?提前谢谢。

1 个答案:

答案 0 :(得分:1)

不要将外连接表的条件添加到WHERE子句,而是添加到ON子句或考虑NULLS。原因如下:一旦外连接表(如PTM)中没有匹配的记录,就会创建一个伪记录,并将所有值设置为NULL。当要求PTM.meId LIKE @themeParam或......你可能会错误地再次消除这些记录。