Cosmos DB中多列DISTINCT及ORDER BY、OFFSET LIMIT联用方法
Cosmos DB多列DISTINCT机制及组合子句使用说明
多列场景下的DISTINCT运行机制
Cosmos DB的DISTINCT去重规则是针对SELECT子句列出的所有投影列的值组合做唯一性校验,并非针对单列去重。只要多行数据投影出的所有字段值完全一致,就会被判定为重复记录,最终仅返回1条。
全量查询SELECT distinct c.Code,c.Name, c._ts FROM c返回100条记录,代表整个集合内(Code, Name, _ts)三个字段组成的唯一值组合共100组。
DISTINCT+ORDER BY+OFFSET LIMIT的执行逻辑与结果差异原因
三个子句组合使用时,Cosmos DB的执行顺序和直觉认知有区别,优先级从高到低如下:
- 优先执行
WHERE条件过滤,筛出所有匹配的原始文档 - 其次执行投影+DISTINCT去重:保留SELECT指定的列,对这些列的组合做去重,生成去重后的中间结果集
- 之后对去重后的中间结果集,按
ORDER BY指定的规则排序 - 最后执行
OFFSET LIMIT,跳过指定条数的排序结果,返回对应数量的记录
测试返回的数量差异完全匹配这个执行逻辑:
- 不带DISTINCT时,
c.Name = 'SomeName'条件匹配到的原始文档共67条,这是未去重的原始数据基数。 - 加上DISTINCT后,67条原始文档投影出的
(Code, Name, _ts)组合去重后共57条,此时执行OFFSET 50 LIMIT 10,会跳过前50条去重排序后的结果,剩余可返回条目仅7条,因此最终返回7条,完全符合引擎执行逻辑,不存在语法错误。
正确使用注意事项
- 使用多列DISTINCT前要明确:去重粒度是所有投影列的组合,如果需要按单个字段去重,不能直接用多列投影+DISTINCT实现,需要先通过子查询按目标字段分组去重后再做关联查询。
- DISTINCT搭配ORDER BY时,ORDER BY指定的排序字段必须包含在SELECT投影列中,否则查询会直接报语法错误。
- 带DISTINCT做分页时,OFFSET的计算基数是去重后的结果集总条数,不是原始匹配文档的条数,不能按原始文档数计算偏移量,否则会出现取数不足、分页错位的问题。
- 需要获取带DISTINCT的分页总条数时,要单独写count查询拿到去重后的总数,参考写法:
SELECT VALUE COUNT(1) FROM ( SELECT DISTINCT c.Code,c.Name,c._ts FROM c WHERE c.Name = 'SomeName' ) t
内容的提问来源于stack exchange,提问作者itaustralia
相关产品推荐
相关产品推荐

