Apache Druid groupBy 查询结果过滤:Having 子句(HavingSpec)完整实战指南

发布时间:2026/9/23 23:15:16

Apache Druid groupBy 查询结果过滤:Having 子句(HavingSpec)完整实战指南 数据库数据分析OLAP大数据实时分析数据仓库后端【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址https://gitcode.com/gh_mirrors/druid7/druid点击查看免费下载Having 子句是 Apache Druid 中用于对 groupBy 查询聚合结果做行级过滤的 JSON 对象其语义与 SQL 的HAVING子句等价常用来实现只返回满足聚合值条件的分组这类查询需求。本文以 docs/content/querying/having.md 为主体骨架完整覆盖其全部过滤类型与 JSON 语法并结合 processing 模块下的HavingSpec源码实现、GroupByQuery 查询解析逻辑及对应测试讲透每种过滤器的配置方式、底层比较规则与使用注意事项帮助你在实际查询中正确编写和调试 having 子句。一、Having 子句是什么在 SQL 中WHERE作用于原始行而HAVING作用于聚合后的分组结果。Druid 的 having 子句与之对应它也是一个 JSON 对象通过指定聚合值上的条件决定 groupBy 查询返回哪些行即哪些分组。以 GroupByQuery.java 中的定义为依据having 子句作为 groupBy 查询 JSON 的一个可选顶层属性存在JsonProperty(having) HavingSpec havingSpec,在查询执行阶段Druid 会先完成分组与聚合再对每个结果行调用HavingSpec.eval(Row)判断该行是否满足条件见 GroupByQuery.java只有eval返回true的行才会进入最终结果。也就是说having 过滤发生在聚合之后、limit 截断之前。Druid 通过JsonTypeInfo(use JsonTypeInfo.Id.NAME, property type)以type字段反序列化不同的 having 子句HavingSpec接口HavingSpec.java中注册的全部类型如下type取值对应实现类语义andAndHavingSpec逻辑与orOrHavingSpec逻辑或notNotHavingSpec逻辑非greaterThanGreaterThanHavingSpec聚合值大于给定值lessThanLessThanHavingSpec聚合值小于给定值equalToEqualToHavingSpec聚合值等于给定值dimSelectorDimensionSelectorHavingSpec维度值等于给定值alwaysAlwaysHavingSpec恒真主要用于测试组合filterDimFilterHavingSpec复用任意 Druid 查询过滤器其中always和not对应的NeverHavingSpec、AlwaysHavingSpec被作为组合单元暴露在HavingSpec接口中HavingSpec.NEVER/HavingSpec.ALWAYS见 HavingSpec.java主要用于逻辑组合与测试。下面按类别逐一介绍每种语法的 JSON 写法。二、查询过滤器Query Filter HavingSpectype 为 filter查询过滤器类型的 HavingSpec 允许把任意 Druid 查询过滤器直接用在 having 部分。其语法为{ type : filter, filter : any Druid query filter }例如使用一个 selector 过滤器{ type : filter, filter : { type: selector, dimension : dimension, value : dimension_value } }从源码实现看DimFilterHavingSpec.javafilter属性是必填的构造器通过Preconditions.checkNotNull(dimFilter, filter)校验它会把传入的DimFilter转成ValueMatcher后再对每一行做匹配因此凡是 filters.md 中列出的过滤器类型selector、regex、bound、javascript 等都可在此复用。特别注意__time字段的差异filter类型的 HavingSpec 作用于输出字段名为__time时行为与其他 HavingSpec 不同——它作用于每一行的时间戳而不是名为__time的输出字段。官方文档明确建议避免将输出字段命名为__time未来版本的 Druid 可能会强制执行这一约束。三、数值过滤器Numeric Filters数值过滤器是最简单的 having 子句直接对聚合指标与给定数值做比较同时也可作为更复杂的布尔表达式过滤器的底层基础。示例{ type: greaterThan, aggregation: myAggMetric, value: 100 }其中aggregation指定要比较的聚合指标名即 groupBy 查询中aggregations数组里定义的输出名value为数值。下面介绍三种数值过滤器。3.1 equalTo等于匹配聚合值等于给定值的行{ type: equalTo, aggregation: aggregate_metric, value: numeric_value }等价于 SQL 的HAVING aggregate value。3.2 greaterThan大于匹配聚合值大于给定值的行{ type: greaterThan, aggregation: aggregate_metric, value: numeric_value }等价于 SQL 的HAVING aggregate value。3.3 lessThan小于匹配聚合值小于给定值的行{ type: lessThan, aggregation: aggregate_metric, value: numeric_value }等价于 SQL 的HAVING aggregate value。3.4 数值比较的底层实现三种数值过滤器最终都通过同一个工具类HavingSpecMetricComparatorHavingSpecMetricComparator.java完成比较其规则如下若聚合结果以Long存储则用Longs.compare(long, value.longValue())做整型比较若聚合结果是字符串且完全匹配整型正则[-|]?\dLONG_PAT则按getLongMetric取出的长整型值比较其他情况浮点等统一回退为Floats.compare(float, value.floatValue())的浮点比较。因此当聚合指标值很大超出浮点精度或希望做精确整型比较时Druid 会优先走整型路径避免精度损失。对应的序列化/反序列化与组合行为在 HavingSpecTest.java 中有完整测试覆盖例如GreaterThanHavingSpec(agg, 1.3)、LessThanHavingSpec与NotHavingSpec组合的序列化验证。四、维度选择过滤器Dimension Selector FilterdimSelector类型的 having 子句匹配维度值等于给定值的行{ type: dimSelector, dimension: dimension, value: dimension_value }注意它与数值过滤器不同数值过滤器比较的是聚合指标而dimSelector比较的是分组维度本身。从实现看DimensionSelectorHavingSpec.javadimension为必填属性构造器通过checkNotNull校验可选属性extractionFn用于在比较前对维度值做提取转换未指定时默认使用IdentityExtractionFn恒等变换由于 Druid 支持多值维度eval会遍历该维度行的所有取值任一值经extractionFn提取后与value相等即命中若维度行值为空且value也为 null/空串同样视为命中。因此可以在 having 阶段结合 extraction functions 做大小写归一、正则提取等复杂匹配。五、逻辑表达式过滤器Logical Expression Filters与 SQL 的AND/OR/NOT对应Druid 提供三种逻辑组合器其内部havingSpecs/havingSpec可以嵌套任意本页介绍的其他 having 子句包括再嵌套逻辑组合。5.1 AND{ type: and, havingSpecs: [having clause, having clause, ...] }havingSpecs中的每个子句可以是本页定义的任意 having 子句。从 AndHavingSpec.java 的实现看它是短路求值的遍历子句一旦某个子句eval返回false立即返回false。5.2 OR{ type: or, havingSpecs: [having clause, having clause, ...] }同样支持任意嵌套。对应 OrHavingSpec.java 的实现也是短路求值任一子句eval返回true即整体为true。5.3 NOT{ type: not, havingSpec: having clause }对单个子句的结果取反见 NotHavingSpec.java。5.4 组合示例利用逻辑组合可以写出等价于复杂 SQL 的过滤条件。例如返回count大于 100 且avg_price小于 10 或category等于 book{ type: and, havingSpecs: [ { type: greaterThan, aggregation: count, value: 100 }, { type: or, havingSpecs: [ { type: lessThan, aggregation: avg_price, value: 10 }, { type: dimSelector, dimension: category, value: book } ] } ] }六、完整 groupBy 查询示例把 having 子句放入 groupBy 查询 JSON 的having顶层属性即可对聚合结果过滤。下面是一个完整的查询聚合定义参考 aggregations.mdgroupBy 查询整体结构参考 groupbyquery.md{ queryType: groupBy, dataSource: wikiticker, granularity: day, dimensions: [channel], aggregations: [ {type: count, name: edits}, {type: longSum, name: added, fieldName: added} ], having: { type: and, havingSpecs: [ {type: greaterThan, aggregation: edits, value: 50}, {type: lessThan, aggregation: added, value: 100000} ] }, intervals: [2015-09-12T00:00:00.000Z/2015-09-13T00:00:00.000Z] }该查询按channel分组统计每日编辑次数与新增字符数最终只返回编辑次数大于 50 且新增字符数小于 100000的频道分组效果等价于 SQL 的GROUP BY channel HAVING edits 50 AND added 100000。七、使用注意事项与性能提示线程安全HavingSpec对象本身不是线程安全的javadoc 与 GroupByQuery.java 的applyLimit注释均明确提示不应被多个线程同时使用也不要在两个不同线程中同时累积本方法返回的两个Sequence。DimFilterHavingSpec更是在eval内部通过evalCount自增检查检测并发调用一旦发现并发会抛出IllegalStateException(concurrent eval calls not permitted!)见 DimFilterHavingSpec.java。输出字段命名避免把输出字段命名为__time因为filter类型 HavingSpec 对它存在特殊语义作用于行时间戳而非字段值。比较精度数值比较优先走整型路径见第三节对长整型聚合结果更精确浮点场景则按 float 比较若对精度敏感需在设计聚合时留意。缓存每种 HavingSpec 都实现了getCacheKey()如equalTo为0x3、greaterThan为0x4、lessThan为0x5、dimSelector为0x8、filter为0x9参与查询缓存键的生成因此不同 having 条件会生成不同的缓存条目可放心使用。八、进一步阅读本文主体docs/content/querying/having.md可复用的查询过滤器清单docs/content/querying/filters.mdgroupBy 查询完整结构与其余属性docs/content/querying/groupbyquery.md聚合定义与输出名docs/content/querying/aggregations.mdHavingSpec 接口与类型注册processing/src/main/java/io/druid/query/groupby/having/HavingSpec.java查询解析与执行入口processing/src/main/java/io/druid/query/groupby/GroupByQuery.java序列化与组合行为测试processing/src/test/java/io/druid/query/groupby/having/HavingSpecTest.java赞分享数据库数据分析OLAP大数据实时分析数据仓库后端【免费下载链接】druidApache Druid: a high performance real-time analytics database.项目地址https://gitcode.com/gh_mirrors/druid7/druid点击查看免费下载相关推荐Apache Druid groupBy 查询 Having 子句完全指南聚合后过滤的 JSON 语法与源码实现Apache Druid groupBy 查询 Having 子句完全指南聚合后过滤的 JSON 语法与源码实现 本篇技术指南聚焦 Apache Druid数据库OLAP大数据后端Apache Druid groupBy 查询的 LimitSpec 完全指南排序与结果限制Apache Druid groupBy 查询的 LimitSpec 完全指南排序与结果限制 limitSpec 是 Apache Druid 原生nati数据库OLAP大数据后端Apache Druid 查询指南使用 LimitSpec 对 groupBy 查询结果排序与限量Apache Druid 查询指南使用 LimitSpec 对 groupBy 查询结果排序与限量 limitSpec 是 Apache Druid grou数据库数据分析OLAP大数据实时分析数据仓库后端上一篇react-jsonschema-form中的表单数据处理完成回调下一篇Odyssey Theme如何用 Astro 打造完美 Lighthouse 评分的现代商业网站创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/23 23:10:16

OpenCV+VS2019+MATLAB双目测距实战:从标定到视差计算

简介:这份资源面向计算机视觉初学者与需要完成课程设计、毕业设计的开发者,提供一套基于OpenCV、VS2019与MATLAB的双目视觉测距完整实现。代码覆盖从相机标定、立体校正到利用BM局部匹配算法输出视差图的全流程,可帮助读者理解双目测距的标定…

2026/9/23 23:10:16

发票表格检测数据集与YOLOv8训练实战指南

简介:发票表格检测数据集.zip 是面向文档结构识别与目标检测场景的行业数据集,含909张真实发票图片及YOLO格式边界框标注,类别聚焦表格区域,适合算法工程师、财务系统开发者和计算机视觉学习者训练或微调YOLOv12等模型&#xff0c…

2026/9/24 0:15:21

SSM毕业设计-基于 SSM 的在线视频教育网站系统的设计与实现 基于 SSM 的线上视频学习系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/24 0:15:21

YOLOv8智慧工地数据集训练实战:从标签转换到排坑全流程

简介:面向工地安全监管与目标检测模型训练,这套YOLO智慧工地数据集提供了7538张带标签图像,标注类别涵盖安全帽、反光衣、头盔、背心、靴子等防护装备,适用于yolo、faster rcnn等主流检测算法的训练与效果验证。压缩包共2000个文件…

2026/9/24 0:15:21

生物识别技术详解:指纹与虹膜识别原理、实现与落地实践

生物识别这四个字,这几年被提得越来越多。手机解锁、门禁通行、支付验证,甚至公司考勤,背后都有它的影子。但很多人对它的理解还停留在“刷指纹”“扫脸”这个层面,真要问一句指纹和虹膜到底是怎么把一个人认出来的,为…

2026/9/24 0:15:21

正态分布与高斯分布:定义、性质、Python实现与实战应用

聊到正态分布和高斯分布,很多刚入行数据分析、机器学习或者做实验科学的同学都会问同一个问题:这俩到底是不是一个东西?它们有什么区别?我第一次做质量分析时也被这俩名字绕晕过,后来搞明白了,答案其实特别…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/24 0:00:21

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:21

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:21

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码