部分计数聚合
Partial count aggregation
注意:虽然我目前的重点是 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
,[产品计数分类] 字段将为 return,如果没有关联的 productID
,则为 0,对于 1,则为 1,对于任何更高的,则为 2+数字。但是,count(distinct productID)
并不会在达到2的时候就停止计算,它会愉快地继续到无穷大,然后再进行一次运算计算这个案例。
我看到同样的事情多次出现。
有没有更有效的方法来实现这个? 如果我们只想要 0/1+ class 答案是半连接 (in/exists) .但是任意数量的范围呢?
您可能无能为力。但这里有两种替代方式来表达可能具有更好性能的查询。
如果您有关于“(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 服务器有更好的优化器,所以它可能不是一个大赢家。
注意:虽然我目前的重点是 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
,[产品计数分类] 字段将为 return,如果没有关联的 productID
,则为 0,对于 1,则为 1,对于任何更高的,则为 2+数字。但是,count(distinct productID)
并不会在达到2的时候就停止计算,它会愉快地继续到无穷大,然后再进行一次运算计算这个案例。
我看到同样的事情多次出现。
有没有更有效的方法来实现这个? 如果我们只想要 0/1+ class 答案是半连接 (in/exists) .但是任意数量的范围呢?
您可能无能为力。但这里有两种替代方式来表达可能具有更好性能的查询。
如果您有关于“(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 服务器有更好的优化器,所以它可能不是一个大赢家。