Where clause with three options

时间:2018-04-20 00:56:49

标签: sql sql-server case sql-server-2016

I'm using SQL Server 2016 Dev and I have a WHERE clause with 3 options.

I solved 2 and I need help on the third one. Please see the code.

I can't use a CTE or any other code because it's part of a legacy code and can't be modified except the case on the where clause.

Requirements

When DepartmentID = 99 then all records
When DepartmentID = 97 then only PriorityID 10 records
All other Departments = all records except PriorityID 10

Sample data

Create table Department
(
    DepartmentID int null,
    PriorityID   int null
)
GO

Insert into Department (DepartmentID, PriorityID) 
values (1, 2), (2, 2), (3, 10), (4, 3), (5, 4), 
       (97, 10), (99, 10), (4, 5), (5, 3), (2, 10),
       (99, 2), (97, 1), (3, 2), (3, 3), (2, 5)
GO

Select * from Department

My query so far

--Declare @intDepartmentID int = 99 OK
--Declare @intDepartmentID int = 97 OK
Declare @intDepartmentID int = 2 -- Need to exclude Record with PriorityID = 10
Declare @intPriorityID int = null

IF @intDepartmentID = 99
Begin
    Set @intDepartmentID = null
    Set @intPriorityID = null
End

If @intDepartmentID = 97
Begin 
    Set @intDepartmentID = null
    Set @intPriorityID = 10
End

Select DepartmentID,
        PriorityID
From Department
Where (DepartmentID = @intDepartmentID or @intDepartmentID is null)
    -- I think I need case statement here?
And (PriorityID = @intPriorityID or @intPriorityID is null)

6 个答案:

答案 0 :(得分:0)

where DepartmemtID = @DepartmentID and
    <add one of the two case expressions below>

    case @DepartmentID
       when 99 then 1
       when 97 then case when PriorityID = 10 then 1 end
       else case when PriorityID <> 10 then 1 end
    end = 1

-- or

    case 
       when @DepartmentID = 99 then 1
       when @DepartmentID = 97 and PriorityID  = 10 then 1
       when @DepartmentID = 97 then 0 -- all other priorities
       when PriorityID <> 10 then 1
    end = 1

第二个是嵌套较少的,并且正如所写的那样,它确实依赖于早期案例的下降。此外,如果你有空值,你也需要调整它。

一般的想法是使用case仅为您感兴趣的条件返回匹配值(在此示例中为1)。因为这些变得更复杂,所以能够很好通过依赖早期的错误案例来压缩逻辑,我认为通常也更容易维护。请记住,订单很重要。

答案 1 :(得分:0)

请检查此查询。

SELECT DepartmentID,
        PriorityID
FROM Department
WHERE ((PriorityID != (CASE  
                WHEN (@intDepartmentID NOT IN (97, 99)) THEN 10
                END) AND @intDepartmentID NOT IN (97,99))
OR (PriorityID = (CASE  
WHEN @intDepartmentID = 99 THEN PriorityID
WHEN @intDepartmentID = 97 THEN 10
END) AND @intDepartmentID IN (97,99))
)
--AND (DepartmentID = @intDepartmentID OR @intDepartmentID is null)  --If you want to filter data by department then enable this condition

答案 2 :(得分:0)

首先,您不需要将@intPriorityID作为参数之一,因为PriorityID值是由@intDepartmentID决定的。

请尝试这个,如果您需要,请告诉我们:

worklist

答案 3 :(得分:0)

真的应该在您的问题中包含您对参数的每个值的预期结果。

根据您对其他答案的评论,我认为您确实希望按DepartmentID进行过滤,而不管@intDepartmentID参数的值是什么,并使用一些额外的逻辑来确定是否要按{过滤{1}}也是。

这是一种方法。

PriorityID

上述比较的简单方法假设SELECT * FROM @Department AS D WHERE (D.DepartmentID = @intDepartmentID) AND ( (@intDepartmentID = 99) OR (@intDepartmentID = 97 AND D.PriorityID = 10) OR (@intDepartmentID NOT IN (97, 99) AND D.PriorityID <> 10) ) OPTION(RECOMPILE); DepartmentIDPriorityID不能是@intDepartmentID。 如果他们可以NULL,正如示例数据中的NULL语句所示,那么请在示例数据中添加几个带有NULL的相关行,以说明数据中的所有情况。此外,请务必在问题中包含预期结果。

这种查询容易出现参数嗅探问题,这就是我添加CREATE TABLE的原因。如果不这样做,此查询的性能可能取决于您第一次运行它时使用的参数值。

答案 4 :(得分:0)

如果我理解了这个问题:

1)@intDepartmentID = 99你想要所有没有过滤器的记录 2)@intDepartmentID = 97 PriorityID = 10您需要@intDepartmentID NOT IN (97, 99)的所有记录 3)使用PriorityID <> 10,您需要指定DepartmentID的所有记录,但需要DepID PriID Visible if: 1 2 @intDepartmentID = 99, @intDepartmentID = 1 2 2 @intDepartmentID = 99, @intDepartmentID = 2 3 10 @intDepartmentID = 99, @intDepartmentID = 3, @intDepartmentID = 97 4 3 @intDepartmentID = 99, @intDepartmentID = 4 5 4 @intDepartmentID = 99, @intDepartmentID = 5 97 10 @intDepartmentID = 99, @intDepartmentID = 97 99 10 @intDepartmentID = 99, @intDepartmentID = 97 4 5 @intDepartmentID = 99, @intDepartmentID = 4 5 3 @intDepartmentID = 99, @intDepartmentID = 5 2 10 @intDepartmentID = 99, @intDepartmentID = 2, @intDepartmentID = 97 99 2 @intDepartmentID = 99 97 1 @intDepartmentID = 99 3 2 @intDepartmentID = 99, @intDepartmentID = 3 3 3 @intDepartmentID = 99, @intDepartmentID = 3 2 5 @intDepartmentID = 99, @intDepartmentID = 2

使用您的测试数据意味着:

Select * 
from Department
where 
    case @intDepartmentID 
        when 99 then 1 
        when 97 then 
            case when (PriorityID = 10) then 1 else 0 end
    else
        case when ((@intDepartmentID = DepartmentID) and (PriorityID <> 10)) then 1 
        else 0 end
    end = 1

这是查询:

\u2718

答案 5 :(得分:0)

最后这可以按预期工作

Where 
( 
    PriorityID = (CASE @intDepartmentID WHEN 99 then PriorityID  WHEN 97 then 10 END )
    OR  (PriorityID != case when @intDepartmentID not in (99,97) then 10 end )
    and (DepartmentID = @intDepartmentID )
)