# QUERY(exp, condition)
从数据集查询满足条件的一个或多个数据。
query函数常用于独立灵活的取数计算、明细填报中取汇总指标数据、跨表数据校验、复杂统计分析计算、动态数据范围权限控制等场景,能够灵活地从数据集中查询并返回满足条件的数据。
# 语法
QUERY(exp, condition)
exp:必需,查询表达式,通常是一个引用数据集字段的表达式。可以根据表达式内容返回单个值、一维数组或二维数组等,具体请参考示例。
condition: 可选,数据集的查询过滤条件,可以关联其他表进行过滤。
示例地址: QUERY (opens new window)
# 示例
- 返回一个值
没有使用ARR函数、聚合函数时,默认总是返回查询结果的第一条数据的值。
比如查询满足[企业基本信息].[经营状态]='存续'
条件的第一条数据的企业名称:IF(QUERY([企业基本信息].[企业名称],[企业基本信息].[经营状态]='存续') IS NOT NULL,TRUE,FALSE)
- 返回一维数组
使用ARR函数将多行查询结果转为一维数组返回。
比如查询过滤我关注的用户的信息:[用户表].[用户ID] IN QUERY(ARR([用户信息].[用户ID]),[用户关注表].[关注人]=$user.id)
- 返回二维数组
使用ARR函数查询多个字段时将多行查询结果转为二维数组返回。
比如查询满足条件的客户信息:QUERY(ARR([用户信息].[用户ID],[用户信息].[用户名称]),[用户信息].[性别]='女' and [用户信息].[年龄]>25 and [用户信息].[注册时间]>'2024-01-01')
- 返回一个聚合值
使用SUM、COUNT等聚合函数将多行数据聚合为一个值返回。
比如查询满足条件的客户数量:(QUERY(COUNT([用户信息].[用户ID]),[用户信息].[性别]='女' and [用户信息].[年龄]>25 and [用户信息].[注册时间]>'2024-01-01'))
- 多个query函数自动合并查询
页面内多个地方使用query函数时,系统会根据查询模型和条件自动合并,减少对发起的查询请求数量。示例参考:TODO
- 全量缓存数据在内存中再计算query函数
页面经常做大量query查询时,如果查询的模型数据量不大,可以把数据集设置为允许下载全量数据,系统将数据先全量缓存到内存中,再在内存中进行query函数计算,提升查询性能。示例参考:TODO
- 与SELECT函数的区别
SELECT 函数只在SQL端计算,SELECT函数表达式必须放在模型的计算字段或过滤条件中使用,而query函数可以独立构造查询,能放在任何可以使用表达式的地方。
# 场景
# 明细填报中取汇总指标数据
常用于表单、superpage等明细查询页面中取汇总数据,减少对数据加工的依赖,简化取数逻辑。
比如在门店的产品销售情况填报表单中,表单在初始化时会按照产品维浮动出产品列表,同时需要将要填报的销售数量、销售金额等指标从业务库的销售明细表中汇总计算出来,传统的做法是需要使用数据加工提前汇总好数据再引用,现在可以直接通过query(sum([销售明细表].[销售数量]))
表达式来取汇总数据。
# 跨表数据校验
在表单填报场景中,经常需要对填报的数据进行跨表校验以确保数据的准确性和一致性。通过QUERY函数可以灵活地获取其他表中的相关数据,实现复杂的跨表业务规则校验,而不需要创建很多临时的数据加工用来取数。
常见的跨表校验场景:
- 唯一性校验
比如在新增用户信息时,需要校验用户手机号是否已被使用:
QUERY(COUNT([用户信息].[手机号]),[用户信息].[手机号]=表单.手机号)>0
- 数据一致性校验
在采购订单填报时,需要校验采购金额是否超过预算限额:
采购金额 > QUERY(SUM([预算表].[剩余金额]),[预算表].[部门ID]=$user.dept_id)
- 业务规则校验
在合同审批表单中,校验经办人是否具有对应的业务权限:
合同金额 <= QUERY([员工权限表].[审批额度],[员工权限表].[员工ID]=$user.id)
# 复杂统计分析计算
在BI报表分析中,经常需要分析销售趋势和业绩达成情况,比如计算最近12个月的累计销售额来评估业务增长情况。或者在预算管理中需要按月跟踪预算执行进度,计算年度累计预算完成率等。
以计算累计销售额为例:
QUERY(SUM([销售表].[销售额]),[销售表].[销售日期].[年月] BETWEEN 起始年月 AND 截止年月)
# 动态数据范围权限控制
在OA系统中管理公司所有的项目建设情况,包括项目的人力资源、合同、进度等信息。一个员工可以参与多个项目并担任不同的项目角色,这些信息单独记录在项目成员表
中。
为了实现基于用户项目角色权限进行数据过滤,可以使用QUERY函数动态控制登录用户的数据范围:[项目信息表].[项目ID] in QUERY(ARR([项目成员表].[项目ID]),[项目成员表].[用户ID]=$user.id)