注意:尽管我目前的重点是tsql,但这很可能是一个更一般的sql问题。
请考虑以下有效但也可伪代码的示例查询:
select
desiredKeyCols,
case count(distinct productID)
when 0 then '0'
when 1 then '1'
else '2+'
end as [Product Count Classification]
from orders
group by desiredKeyCols
对于每个desiredKeyCols
,如果没有关联的productID
,则[产品计数分类]字段将返回0;对于1,返回1;对于更高的数字,返回2+。但是,count(distinct productID)
一旦达到2就不会停止其计算。它会很高兴地继续到无穷大,然后另一个操作将计算大小写。
我看到同一件事多次出现。
是否有更有效的方法来实现此目的?如果我们只希望0/1 +类,答案是半联接(存在)。但是任意数量的范围呢?
答案 0 :(得分:1)
您可能无能为力。但是,这里有两种替代的方式来表达可能具有更好性能的查询。
如果您在“(desiredKeycols,productid)”上有一个索引,并且可能在“(desiredKeycols,productid desc)”上有一个索引,则可以尝试:
select desiredKeycols,
(case distinct_cnt . . . )
from (select o.*,
(dense_rank() over (partition by desiredKeycols order by productid) +
dense_rank() over (partition by desiredKeycols order by productid desc)
) as distinct_cnt
from orders o
) o
group by desiredKeycols;
这不会在“ 3”处停止,但有可能比count(distinct)
的优化效果更好。
实际上,稍作选择只能使用一个索引:
select desiredKeycols,
(case cnt . . . )
from (select o.desiredKeycols, count(*) as cnt
from orders o
group by desiredKeycols, productid
) o
group by desiredKeycols;
在某些数据库中,这比count(distinct)
快得多。但是,我认为SQL Server具有更好的优化器,因此这可能不是一个大胜利。