注意:尽管我目前的重点是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
,将返回0,如果没有关联的productID
,则1表示1,2+表示更大的数字。但是,count(distinct productID)
到达2时将不会停止其计算。它会很高兴地继续到无穷大,然后另一个运算将计算大小写。
我见过同一件事多次出现。
有没有更有效的方法来实现这一点?如果我们只需要0/1 +类,答案是半联接(存在)。但是,任意数量的范围呢?
您可能无能为力。但是这里有两种替代的方式来表达可能具有更好性能的查询。
如果您在“(desiredKeycols,productid)”上可能有一个索引,则可以尝试::
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具有更好的优化程序,因此它可能不是一个大赢家。