How to tweak WHERE clause to select all records without Premium = 0 when passing NULL as a parameter in SQL statement

拈花ヽ惹草 提交于 2019-12-25 00:23:20

问题


The result should return:

  • If @reasonID = 1 I need to select only policies that have reasonID = 211
  • If @reasonID = 2 I need to select only policies that have reasonID <> 211 including reasonID IS NULL
  • If @reasonID = NULL I need to select all policies including NULL and Premium <> 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!