Qlik Sense求和表达式解析及等效查询结果不符问题咨询
问题解析与解决方案
一、原Qlik Sense表达式逻辑解析
原表达式代码:
num(sum({1<[report_date] = {"=$(=(date((currDate))))"}> +1<[report_date]={"=$(date(currDate) - 7)"}> +1<[report_date]={"=$(date(currDate) - 30)"}> } anomoly_count ) / 100 )
拆解核心逻辑:
{1<...> + 1<...> + 1<...>}:Qlik的集合表达式,1表示忽略仪表盘上的所有外部筛选条件,三个独立的<report_date=...>规则用+合并,等价于提取currDate、currDate-7、currDate-30这三天的所有anomoly_count记录。sum(anomoly_count):对这三天的anomoly_count做求和计算。/100:将求和结果除以100。num():对最终结果做数字格式化(如小数位数、千分位,默认遵循Qlik系统设置)。
二、等效数据库查询结果不一致的原因与修正
你的SQL查询和Qlik表达式存在3个关键差异:
- 筛选器忽略逻辑:Qlik表达式里的
1会完全忽略仪表盘上的其他筛选(比如维度选择、额外日期过滤),但你的SQL未考虑这一点,若仪表盘运行时存在其他筛选,会导致结果偏差。 - 日期格式匹配:Qlik的
date()函数输出格式可能与数据库report_date::date的格式不兼容(比如Qlik输出MM/DD/YYYY,数据库是YYYY-MM-DD),导致日期匹配失败。 - 隐性关联过滤:若Qlik数据模型中
summary表与其他表存在关联,可能会自动过滤部分记录,你的SQL未加入对应关联逻辑。
修正后的SQL(模拟Qlik忽略外部筛选的逻辑):
WITH sum_count AS ( SELECT SUM(anomoly_count) as sum_anomoly_count FROM "summary" WHERE -- 确保日期与Qlik变量currDate生成的格式完全一致 report_date::date IN ('2023-05-11', '2023-05-04', '2023-04-11') -- SUM函数会自动忽略NULL值,无需额外过滤 ) SELECT (sum_count.sum_anomoly_count ::NUMERIC / 100) as result FROM sum_count
额外检查点:
- 确认Qlik中
currDate的定义:是系统当前日期还是自定义变量?确保SQL中使用的日期与该变量完全一致。 - 检查Qlik数据模型:若
summary表有关联表,需在SQL中加入相同的关联过滤条件。
三、实现目标需求的方法(currDate数值 + 过去7天平均值 + 过去30天平均值)
1. Qlik Sense表达式实现
num( -- 取currDate当天的anomoly_count总和 sum({1<[report_date]={"=$(date(currDate))"}>} anomoly_count) -- 加上过去7天(含currDate,共7天)的日平均值 + avg({1<[report_date]={">=$(date(currDate)-6) <=$(date(currDate))"}>} anomoly_count) -- 加上过去30天(含currDate,共30天)的日平均值 + avg({1<[report_date]={">=$(date(currDate)-29) <=$(date(currDate))"}>} anomoly_count) )
说明:
- 若
过去7天定义为不含currDate的前7天,将日期范围改为">=$(date(currDate)-7) <$(date(currDate))"即可。 - 若需要结果受仪表盘外部筛选影响,去掉集合表达式中的
1。
2. 等效数据库查询实现
WITH daily_data AS ( SELECT report_date::date AS dt, SUM(anomoly_count) AS day_sum FROM "summary" WHERE -- 取过去30天的数据(含currDate),若currDate是变量则替换为具体值 report_date::date BETWEEN (CURRENT_DATE - 29) AND CURRENT_DATE GROUP BY report_date::date ), avg_7d AS ( SELECT AVG(day_sum) AS avg_7 FROM daily_data WHERE dt BETWEEN (CURRENT_DATE - 6) AND CURRENT_DATE ), avg_30d AS ( SELECT AVG(day_sum) AS avg_30 FROM daily_data WHERE dt BETWEEN (CURRENT_DATE - 29) AND CURRENT_DATE ), curr_day_sum AS ( SELECT day_sum AS curr_sum FROM daily_data WHERE dt = CURRENT_DATE ) SELECT curr_day_sum.curr_sum + avg_7d.avg_7 + avg_30d.avg_30 AS result FROM curr_day_sum, avg_7d, avg_30d
内容的提问来源于stack exchange,提问作者BlendinBlandin
相关产品推荐
相关产品推荐

