使用大小写而不是IF ELSE来更改SQL中的WHERE子句

时间:2016-08-31 14:49:20

标签: sql sql-server if-statement case

我正在尝试构建一个查询,其中where子句根据外部变量稍微改变,我想出了下面的脚本

IF(@threshold='N')

  select  min_price
  ,       s.customization_type
  ,       gii.brand
  ,       gii.item_flag
  from   item_info gii
  ,      style s
  ,      categories gpc  
  where  isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
  and    gii.segment1 = s.style_number   
  and    gpc.line_of_business_category = 'AAA'
  and    gii.inventory_item_id = @v_item_id;

ELSE 
      select  min_price
  ,       s.customization_type
  ,       gii.brand
  ,       gii.item_flag
  from   item_info gii
  ,      style s
  ,      categories gpc  
  where  isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
  and    gii.segment1 = s.style_number   
  and    gpc.line_of_business_category = 'BBB'
  and    gii.inventory_item_id = @v_item_id;

但是,我觉得上面的查询并不干净,尽管它给出了理想的结果。有没有更好的方法可以优化此查询,例如使用CASE WHEN?

6 个答案:

答案 0 :(得分:3)

据我所知,你只需改变这一行:

gpc.line_of_business_category = 'AAA'

gpc.line_of_business_category = CASE 
                                   WHEN @threshold='N' THEN 'AAA' 
                                   ELSE 'BBB'
                                END

如果您使用SQL Server 2012或更新版本,则IIF是另一种选择:

gpc.line_of_business_category = IIF(@threshold='N', 'AAA', 'BBB') 

答案 1 :(得分:1)

当然,您可以使用case表达式:

select  min_price
  ,       s.customization_type
  ,       gii.brand
  ,       gii.item_flag
  from   item_info gii
  ,      style s
  ,      categories gpc  
  where  isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
  and    gii.segment1 = s.style_number   
  and    gpc.line_of_business_category = case when @threshold='N' then 'AAA' else 'BBB' end
  and    gii.inventory_item_id = @v_item_id;

答案 2 :(得分:1)

  select  min_price
  ,       s.customization_type
  ,       gii.brand
  ,       gii.item_flag
  from   item_info gii
  ,      style s
  ,      categories gpc  
  where  isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
  and    gii.segment1 = s.style_number   
  and    gii.inventory_item_id = @v_item_id;

  and    gpc.line_of_business_category = (CASE WHEN @threshold='N' THEN 'AAA' ELSE 'BBB' END)

但是你应该使用显式连接语法!

使用显式连接语法时,在调试代码时,您的意图会更清晰:

select
    min_price
    ,s.customization_type
    ,gii.brand
    ,gii.item_flag
from 
    item_info gii
    INNER JOIN style s
    ON gii.segment1 = s.style_number
    INNER JOIN categories gpc
    ON isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
    and gpc.line_of_business_category = (CASE WHEN @threshold='N' THEN 'AAA' ELSE 'BBB' END)
WHERE
    gii.inventory_item_id = @v_item_id;

此外,它会开始向您显示何时可能存在关系问题,例如您的类别gpc。我看到该表与其他1个表没有直接关系,而是你选择了那些然后交叉连接的类别我知道你的意图吗?

答案 3 :(得分:1)

您可以使用如下:

where gpc.line_of_business = case when @threshold='N' then 'AAA' else 'BBB' end

答案 4 :(得分:0)

您确实可以在查询中使用CASE语句,如下所示,尽可能少地修改查询:

select min_price
    , s.customization_type
    , gii.brand
    , gii.item_flag
from   item_info gii
    , style s
    , categories gpc  
where isnull(@ordered,getdate()) 
    between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
    and gii.segment1 = s.style_number   
    and 1 = CASE 
             WHEN @threshold='N' AND gpc.line_of_business_category = 'AAA'
                 THEN 1
             WHEN @threshold <> 'N' AND gpc.line_of_business_category = 'BBB'
                 THEN 1
          ELSE 0
      END
and gii.inventory_item_id = @v_item_id;

答案 5 :(得分:0)

只需使用

  and ( (@threshold ='N' AND gpc.line_of_business_category = 'AAA')
     or (@threshold<>'N' AND gpc.line_of_business_category = 'BBB') )

完整的查询将是

select  min_price
  ,       s.customization_type
  ,       gii.brand
  ,       gii.item_flag
  from   item_info gii
  ,      style s
  ,      categories gpc  
  where  isnull(@ordered,getdate()) between gpc.start_date and isnull(gpc.end_date, dateadd(day, 1, getdate()))
  and    gii.segment1 = s.style_number   
  and ( (@threshold ='N' AND gpc.line_of_business_category = 'AAA')
     or (@threshold<>'N' AND gpc.line_of_business_category = 'BBB') )
  and    gii.inventory_item_id = @v_item_id;