我正在尝试构建一个查询,其中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?
答案 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;