问题
The result should return:
- If
@reasonID = 1
I need to select only policies that havereasonID = 211
- If
@reasonID = 2
I need to select only policies that havereasonID <> 211
includingreasonID IS NULL
- If
@reasonID = NULL
I need to select all policies includingNULL
andPremium <> 0
The below example works for @reasonID = 1
and @reasonID = 2
:
@reasonID = 1
@reasonID = 2
But how can I tweak the WHERE
clause to select all rows when @reasonID = NULL
? Because it returns policies that have Premium = 0
, which I do not need.
@reasonID = NULL
declare @TempTable1 table (ControlNo int, PolicyNumber varchar(50), Premium money)
insert into @TempTable1
values (1, 'Pol1', 100), (2, 'Pol2', 0), (3, 'Pol3', 50), (4, 'Pol4', 0),
(5, 'Pol5', 70), (6, 'Pol6', 0), (7, 'Pol7', 30)
declare @TempTable2 table (ControlNo int, PolicyNumber varchar(50), reasonID int)
insert into @TempTable2
values (1, 'Pol1', 5), (2, 'Pol2', NULL), (3, 'Pol3', 211),
(4, 'Pol4', 8), (5, 'Pol5', 211), (6, 'Pol6', NULL),
(7, 'Pol7', 3)
--select * from @TempTable1
--select * from @TempTable2
--Here I input @reasonID parameter
declare @reasonID int = NULL
select
T2.ControlNo, T2.PolicyNumber, T1.Premium, T2.reasonID
from
@TempTable1 T1
inner join
@TempTable2 T2 on t1.ControlNo = T2.ControlNo
where
T1.Premium <> 0
and (case when reasonID = 211 then 1 else 2 end = @reasonID) --works for @reasonID = 1 or @reasonID = 2
or (@reasonID IS NULL) --does not work
But should be like that:
Is any way to modify WHERE
clause to achieve desirable result without using HAVING
clause or GROUP BY
?
回答1:
I think you may have missed to add one parenthesis. Also, I modified your case statement in where condition because your else condition will take consideration of null values as well. Since you have or condtion for nulls it does not matter right now. I assumed you may not want null condition in your case statement so I changed it.I did not see Policy 8 in your input, so it does not generate the output of 8. rest is same.
declare @TempTable1 table (ControlNo int,PolicyNumber varchar(50), Premium money)
insert into @TempTable1 values (1,'Pol1', 100),
(2,'Pol2', 0),
(3,'Pol3', 50),
(4,'Pol4', 0),
(5,'Pol5', 70),
(6,'Pol6', 0),
(7, 'Pol7',30)
declare @TempTable2 table (ControlNo int,PolicyNumber varchar(50), reasonID int)
insert into @TempTable2 values (1,'Pol1', 5),
(2,'Pol2', NULL),
(3,'Pol3', 211),
(4,'Pol4', 8),
(5,'Pol5', 211),
(6,'Pol6', NULL),
(7,'Pol7',3)
--select * from @TempTable1
--select * from @TempTable2
--Here I input @reasonID parameter
declare @reasonID int = NULL
select T2.ControlNo,T2.PolicyNumber, T1.Premium, T2.reasonID
from @TempTable1 T1
inner join @TempTable2 T2 on t1.ControlNo = T2.ControlNo
where T1.Premium <> 0
and ((case when reasonID = 211 then 1
when isnull(reasonID,'') not in (211,'') then 2 end = @reasonID) --works for @reasonID = 1 or @reasonID = 2
OR (@reasonID IS NULL)) --does not work (added parentheses)
Output: Now it does not bring premium <> 0
ControlNo PolicyNumber Premium reasonID
1 Pol1 100.00 5
3 Pol3 50.00 211
5 Pol5 70.00 211
7 Pol7 30.00 3
回答2:
I believe you need something like this:
select *
from @TempTable1 t1
join @TempTable2 t2 on t1.ControlNo = t2.ControlNo
where t1.Premium <> 0
and (
(@reasonID is null)
or
(@reasonID = 1 and t2.reasonID = 211)
or
(@reasonID = 2 and (t2.reasonID <> 211 or t2.reasonID is null))
)
Data:
declare @TempTable1 table (ControlNo int,PolicyNumber varchar(50), Premium money)
insert into @TempTable1 values (1,'Pol1', 100),
(2,'Pol2', 0),
(3,'Pol3', 50),
(4,'Pol4', 0),
(5,'Pol5', 70),
(6,'Pol6', 0),
(7, 'Pol7',30),
(8, 'Pol8',10)
declare @TempTable2 table (ControlNo int,PolicyNumber varchar(50), reasonID int)
insert into @TempTable2 values (1,'Pol1', 5),
(2,'Pol2', NULL),
(3,'Pol3', 211),
(4,'Pol4', 8),
(5,'Pol5', 211),
(6,'Pol6', NULL),
(7,'Pol7',3),
(8,'Pol8',null)
For @reasonID = null
:
ControlNo PolicyNumber Premium ControlNo PolicyNumber reasonID
----------- ------------ --------------------- ----------- ------------ -----------
1 Pol1 100.00 1 Pol1 5
3 Pol3 50.00 3 Pol3 211
5 Pol5 70.00 5 Pol5 211
7 Pol7 30.00 7 Pol7 3
8 Pol8 10.00 8 Pol8 NULL
For @reasonID = 1
:
ControlNo PolicyNumber Premium ControlNo PolicyNumber reasonID
----------- ------------ --------------------- ----------- ------------ -----------
3 Pol3 50.00 3 Pol3 211
5 Pol5 70.00 5 Pol5 211
For @reasonID = 2
:
ControlNo PolicyNumber Premium ControlNo PolicyNumber reasonID
----------- ------------ --------------------- ----------- ------------ -----------
1 Pol1 100.00 1 Pol1 5
7 Pol7 30.00 7 Pol7 3
8 Pol8 10.00 8 Pol8 NULL
来源:https://stackoverflow.com/questions/55054756/how-to-tweak-where-clause-to-select-all-records-without-premium-0-when-passing