使用Case或Join的TSQL Select语句

时间:2015-04-21 22:44:28

标签: sql-server tsql stored-procedures sql-server-2012

我有点陷入一种我一直在努力争取的局面。我有一个页面,允许用户选择他们想要搜索的所有过滤器选项,然后它运行对该数据的查询。

每个领域都需要挑选一些东西,但在我介绍的新领域,它将是可选的。

它允许您提供主管列表,然后它将提供代理主管在提供的列表中的所有记录;很直接。但是,我正在努力使这个可选,因为我不想总是用户搜索。如果我没有在UI中提供一个名称来传递给存储过程,那么我想忽略该语句的这一部分,无论经理如何都能得到我所有的信息。

以下是我正在使用的查询:

SELECT a.[escID],
           a.[escReasonID],
           b.[ArchibusLocationName],
           c.[ArchibusLocationName],
           b.[DepartmentDesc],
           c.[DepartmentDesc],
           a.[escCreatedBy],
           a.[escWorkedBy],
           a.[escNotes],
           a.[preventable],
           a.[escalationCreated],
           a.[escalationTracked],
           a.[feedbackID],
           typ.[EscalationType],
           typ.[EscalationTypeText] AS escalationType,
           d.reasonText AS reasonText
    FROM   [red].[dbo].[TFS_Escalations] AS a
           LEFT OUTER JOIN
           red.dbo.EmployeeTable AS b
           ON a.escCreatedBy = b.QID
           LEFT OUTER JOIN
           red.dbo.EmployeeTable AS c
           ON a.escWorkedBy = c.QID
           LEFT OUTER JOIN
           red.dbo.TFS_Escalation_Reasons AS d
           ON a.escReasonID = d.ReasonID
           INNER JOIN
           dbo.TFS_EscalationTypes AS typ
           ON d.escType = typ.EscalationType
    WHERE  B.[ArchibusLocationName] IN (SELECT location
                                        FROM   @tmLocations)
           AND C.[ArchibusLocationName] IN (SELECT location
                                            FROM   @subLocations)
           AND B.[DepartmentDesc] IN (SELECT department
                                      FROM   @tmDepartments)
           AND C.[DepartmentDesc] IN (SELECT department
                                      FROM   @subDepartments)
           AND DATEDIFF(second, '19700101', CAST (CONVERT (DATETIME, A.[escalationCreated], 121) AS INT)) >= @startDate
           AND DATEDIFF(second, '19700101', CAST (CONVERT (DATETIME, A.[escalationCreated], 121) AS INT)) <= @endDate
           AND a.[PREVENTABLE] IN (SELECT PREVENTABLE FROM @preventable)
           AND b.MgrQID IN (SELECT leaderQID FROM @sourceLeaders)

我尝试选择的部分是查询的最后一行:

AND b.MgrQID IN (SELECT leaderQID FROM @sourceLeaders)

基本上,如果临时表@sourceLeaders中没有数据,那么它应该忽略该部分查询。

WHERE子句的所有其他实例中,这些字段总是需要一些东西,这就是为什么一切正常。我只是想弄清楚这个部分是否可选的最佳方法,具体取决于临时表中是否有数据(临时表由用户可以搜索的UI中输入的名称填充)。

3 个答案:

答案 0 :(得分:3)

因此,如果某些内容与表变量中的数据匹配或者表变量中没有任何内容,则此行应为TRUE

AND 
(
   b.MgrQID IN (SELECT leaderQID FROM @sourceLeaders)
   OR
   NOT EXISTS (SELECT 1 FROM @sourceLeaders)
)

答案 1 :(得分:0)

与Nick.McDermaid类似,但改为使用案例陈述:

AND 
(
   1 = CASE WHEN NOT EXISTS(SELECT 1 FROM @sourceLeaders) THEN  1
            WHEN b.MgrQID IN (SELECT leaderQID FROM @sourceLeaders) THEN 1
            ELSE 0 
       END 
)   

答案 2 :(得分:0)

也许在顶部,所以你只有一张支票

DECLARE @EmptySourceLeaders CHAR(1)
IF EXISTS (SELECT 1 FROM @sourceLeaders)
   SET @EmptySourceLeaders = 'N'
ELSE 
   SET @EmptySourceLeaders = 'Y'

然后在联接中

LEFT OUTER JOIN @SourceLeaders SL
ON b.MgrQID = SL.leaderQID

然后在WHERE

AND  (@EmptySourceLeaders = 'Y' OR SL.leaderQID IS NOT NULL)

有很多方法可以做到。