我有下表dbo.Product
:
Name Amount
----------
A 10
B 4
C 6
D 3
A 7
我有条件:如果名称等于“ A”,则显示代码“ X”,折扣为“ 10%”,否则显示代码“ Y”,折扣为“ 5%”
我想修改以下查询,您能否建议更好的解决方案:
select
case p.Name
when 'A' then 'X' else 'Y' end as Code,
case p.Name
when 'A' then (p.Amount * 0.1) else (p.Amount * 0.05) end as Discount,
p.Name,
p.Amount
from
dbo.Product as P
答案 0 :(得分:2)
一种方法是:
Select
p.Name,
p.Amount,
'X' as Code,
p.Amount * 0.1 as Discount
from
dbo.Product as P
where p.Name = 'A'
Union All
Select
p.Name,
p.Amount,
'Y' as Code,
p.Amount * 0.05 as Discount
from
dbo.Product as P
where p.Name != 'A';
!=在SQL Server中: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/not-equal-to-transact-sql-exclamation?view=sql-server-2017
数据库小提琴:
Select @@version;
Create Table Product (Name varchar(1), Amount money);
Insert into Product values ('A', 10);
Insert into Product values ('B', 4);
Insert into Product values ('C', 6);
Insert into Product values ('D', 3);
Insert into Product values ('A', 7);
Select
case p.Name
when 'A' then 'X' else 'Y' end as Code,
case p.Name
when 'A' then (p.Amount * 0.1) else (p.Amount * 0.05) end as Discount,
p.Name,
p.Amount
from
Product as P;
Select
'X' as Code,
p.Amount * 0.1 as Discount,
p.Name,
p.Amount
from
dbo.Product as P
where p.Name = 'A'
Union all
Select
'Y' as Code,
p.Amount * 0.05 as Discount,
p.Name,
p.Amount
from
dbo.Product as P
where p.Name != 'A';
答案 1 :(得分:2)
还有其他编写此查询的方法-但在select子句中使用case表达式似乎是最佳选择。
我已将您的样本数据并乘以840行,以便对性能有一些了解。然后,我测试了三种不同的方法来获得预期的结果:
首先,来自问题的查询-它在这三个方面均表现最佳。 第二,Gauravsa建议的并集所有查询,第三,交叉应用版本。
(在我的服务器上)结果如下:
案例表达:16%
全部合并:36%
交叉申请:48%
从结果中可以清楚地看到,case表达式版本是迄今为止的赢家-主要是因为与表扫描或索引扫描甚至是索引查找相比,计算标量的操作非常便宜。
请注意,我已经在没有索引的临时表上进行了测试,因此使用真实实时数据进行的测试可能会产生不同的结果-但是我不认为结果的顺序会发生变化-我的意思是,大小写表达式版本可能仍然会赢。
比起说来,从2012年版本开始,有一种写简单的case表达式的较短方法:IFF函数。
select
IIF(p.Name = 'A', 'X', 'Y') as Code,
IIF(p.Name = 'A', 0.1, 0.05) * p.Amount as Discount,
p.Name,
p.Amount
from
#Product as P
此查询与问题中的查询完全相同-只需较少的代码。
这是我测试中的完整脚本,因此任何人都可以重复该脚本或以我测试的方式发现问题:(the result execution plan can be found here)
-- Create sample data
create table #Product
(
Name char(1),
Amount int
);
insert into #Product (Name, Amount) values
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),
('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7),('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7), ('A', 10), ('B', 4), ('C', 6), ('D', 3), ('A', 7);
-- Cross apply version: nice trick, too slow.
select
Code,
Discount,
p.Name,
p.Amount
from
#Product as P
cross apply
(
select 'X' as code, p.Amount * 0.1 As Discount
where p.Name = 'A'
union all
select 'Y', p.Amount * 0.5
where p.Name <> 'A'
) x
-- Case expression: OP's query
select
case p.Name
when 'A' then 'X' else 'Y' end as Code,
case p.Name
when 'A' then (p.Amount * 0.1) else (p.Amount * 0.05) end as Discount,
p.Name,
p.Amount
from
#Product as P
-- Union all - Gauravsa's query
select
p.Name,
p.Amount,
'X' as Code,
p.Amount * 0.1 as Discount
from
#Product as P
where p.Name = 'A'
union all
select
p.Name,
p.Amount,
'Y' as Code,
p.Amount * 0.05 as Discount
from
#Product as P
where p.Name != 'A'
-- Clean up
drop table #Product
答案 2 :(得分:0)
在如下所示的单个查询中尝试此操作
Select
p.Name,
p.Amount,
CASE WHEN p.Name = 'A' THEN 'X' ELSE 'Y' END as Code,
CASE WHEN p.Name <> 'A' THEN (p.Amount * 0.1) ELSE (p.Amount * 0.05) END as Discount,
from dbo.Product as P