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)
答案 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);
,DepartmentID
和PriorityID
不能是@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 )
)