部分计数汇总

问题描述 投票:1回答:1

注意:尽管我目前的重点是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 +类,答案是半联接(存在)。但是,任意数量的范围呢?

sql sql-server tsql query-performance
1个回答
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具有更好的优化程序,因此它可能不是一个大赢家。

© www.soinside.com 2019 - 2024. All rights reserved.