我有一张产品销售表,看起来可能如下:
product | amount | ptype | pdate p1 | 1.00 | sale | 01/01 p1 | 2.00 | base | 01/02 p2 | 1.50 | sale | 02/03 p3 | 5.25 | base | 10/10
我想建立一个表格,每行显示一个产品,金额的总和,如果产品是唯一的,则显示类型,否则将类型显示为“ VAR”,如果产品是唯一的,则显示日期,否则显示日期为NULL。这样结果看起来如下:
product | total | ptype | pdate p1 | 3.00 | VAR | (NULL) p2 | 1.50 | sale | 02/03 p3 | 5.25 | base | 10/10
我通过执行以下操作来完成所需的结果:
SELECT DISTINCT product ,(SELECT SUM(amount) FROM T as b GROUP BY b.product HAVING a.product = b.product ) as total ,(SELECT CASE WHEN COUNT(*) = 1 THEN a.ptype ELSE 'VAR' END from T as b GROUP BY b.product HAVING a.product = b.product) as ptype ,(SELECT CASE WHEN COUNT(*) = 1 THEN a.pdate ELSE NULL END from T as b GROUP BY b.product HAVING a.product = b.product) as pdate FROM T as a
但是我想知道是否有一种更有效的方法可以达到相同的结果。
无需使用任何形式的子查询或内联视图。根据数据库引擎的复杂程度,这些构造可能会对性能产生负面影响。
这就是您的要求,即使在最原始的SQL引擎上,也只需对表进行一次扫描就可以可靠地给出结果。
select product, sum(amount) as amount, case when count(*)=1 then min(ptype) else 'VAR' end as ptype, case when count(*)=1 then min(pdate) else null end as pdate from T group by product
以下内容与您要求的不完全相同,但是我认为它可能更接近您实际想要的内容。仅当有多个不同的值构成聚合时,才将ptype报告为VAR或pdate报告为NULL。
我添加了一个pcount列,以便即使ptype和pdate都不为nulll,您仍然可以标识单重态集合。
select product, sum(amount) as amount, count(*) as pcount, case when count(distinct ptype)=1 then min(ptype) else 'VAR' end as ptype, case when count(distinct pdate)=1 then min(pdate) else null end as pdate from T group by product