语义视图能力与限制参考
本文集中说明语义视图支持的能力和当前边界,供你在设计视图或排查报错时查阅。每条能力和限制都附最小复现 SQL 和真实输出/报错。
功能概述
语义视图通过声明式定义把多表关系、维度和指标沉淀为业务语义层。指标支持通用聚合函数、算术表达式、条件聚合和窗口函数,DDL 支持
CREATE OR REPLACE 和 SHOW CREATE 回读定义。仍有少数边界(窗口函数的 PARTITION BY 用维度限定名且受同表约束、跨表指标相除等),设计前先了解这些边界可以避免"创建成功但查询出错"这类问题。需要完整查询语法见查询语义视图,跨表关系的聚合粒度见语义视图关系建模与聚合粒度。
指标定义能力
指标体是标准的聚合表达式,支持范围很广:
- 通用聚合函数:不限于
/COUNT
/SUM
/AVG
/MIN
,还包括MAX
、COUNT(DISTINCT ...)
、SUM(DISTINCT ...)
、APPROX_COUNT_DISTINCT
、STDDEV
、VARIANCE
、MEDIAN
、PERCENTILE(col, p)
、GROUP_CONCAT
等。ANY_VALUE - 条件聚合:
,以及标准 SQL 的COUNT(CASE WHEN ...)
过滤指标——每个聚合的过滤条件独立生效,可在同一视图里并列定义分段 KPI 并一起查询。<聚合函数>(...) FILTER (WHERE <条件>) - 算术表达式指标:
、MAX(col) - MIN(col)
、SUM(col) / COUNT(col)
这类在指标体内直接做运算是支持的,单独查询和与其他指标混查都返回正确结果。SUM(col) * 100.0 / SUM(col)
派生指标(同表) —— 支持。同一逻辑表内既可把两个聚合的比值直接写在一个指标体里,也可引用同表已命名的其他指标做运算:
两种写法都支持,且可组合同表任意已命名指标。
窗口函数指标 —— 支持。可在指标体内使用窗口函数(
RANK()/ROW_NUMBER() 等排名,或 SUM(SUM(...)) OVER (...) 这类聚合套窗口做占比、累计),但 PARTITION BY / ORDER BY 有三条约束:
- 必须引用维度的限定别名(如
),不能用物理列名(orders.region
)或裸别名(o_region
),否则报region
或must reference a declared dimension by its alias
。cannot resolve column - partition/order 维度受同表约束:只能是指标所在逻辑表的维度;跨表引用父表维度(如指标在
、orders
)报PARTITION BY customers.region
。cannot resolve column - 查询时该维度必须出现在
的semantic_view()
中,否则报明确语义错。DIMENSIONS
具体示例与实测输出见创建语义视图的"带窗口函数指标的语义视图"。
以下指标定义仍不受支持:
跨表指标相除 —— 一个指标体只能引用自己所在表的列,不能引用其他表的列。例如在
customer 表的指标里写 COUNT(customer.c_custkey) / COUNT(nation.n_nationkey),会因引用不到 nation 的列而报 cannot resolve column 'n_nationkey'。派生指标只能组合同表的聚合(见上文"派生指标")。要聚合更细子表的列,用双层聚合或 FACTS 透传(见下文"跨表指标与粒度")。
NULL 值处理
语义视图的 NULL 处理遵循标准 SQL 语义,几个容易困惑的点:
- NULL 维度值单独成组,不会被丢弃。按含 NULL 的维度分组时,所有 NULL 行聚成一个
分组参与聚合。NULL - 聚合函数跳过 NULL:
/SUM
/AVG
/MIN
/MAX
都忽略 NULL 值。因此COUNT(<列>)
的分母是非 NULL 行数,不是总行数;AVG
只数非 NULL,而COUNT(<列>)
数全部行——同一组里这两个值可能不同。COUNT(<主键>) - 空结果集:对空表或过滤后无行的分组,
返回COUNT
,0
/SUM
等返回AVG
(不报错)。NULL - 除法零除返回 NULL:派生指标里若分母算出
(如0
恰好为 0),该指标返回SUM(x) / (COUNT(a) - COUNT(b))
而不是报错。因此无需为零除额外加保护,但要注意结果中的NULL
可能来自零除而非缺数据。NULL
元数据子句
维度元数据子句在
CREATE 时的书写顺序是固定的:WITH SYNONYMS 必须写在 is_unique/is_time/enum_values 之前,否则报语法错误(Syntax error at or near 'WITH')。
这些子句会持久化,可通过
DESC EXTENDED 回读,但回读保真度不一:
(可多个)、WITH SYNONYMS
—— 回读值与创建值一致。enum_values
、is_unique
—— 只反映"是否声明过",不反映设定的值:只要在is_time
时写了该子句,CREATE
一律回读为DESC EXTENDED
(即便创建时写的是true
);完全不写该子句时,= false
中不出现对应行。因此不能依赖DESC EXTENDED
判断DESC EXTENDED
/is_unique
的真实取值,应以创建脚本为准。is_time
回读的 DDL 只含SHOW CREATE SEMANTIC VIEW
,不含WITH SYNONYMS
/is_unique
/is_time
;需要看这些用enum_values
。DESC EXTENDED
需要过滤时,用
FILTER (WHERE ...) 条件聚合指标(见"指标定义能力"),或在 semantic_view() 外层用 WHERE + 维度短名实现。
查询参数(VARIABLES)
VARIABLES 子句在 CREATE 时声明查询参数,让维度/指标表达式引用一个可在查询时绑定的命名变量,同一视图适配多套阈值/口径。几个要点:
- 子句位置固定:
必须紧跟VARIABLES
之后、TABLES
/FACTS
/DIMENSIONS
之前,写在后面报METRICS
。Syntax error at or near 'VARIABLES' - 声明形式:
。<变量名> <类型> [ DEFAULT <值> | = <值> ]
与DEFAULT
等价,回读时都规范化为=
;不带默认值的变量,只要被引用就必须在查询时绑定。DEFAULT - 引用方式:表达式里用裸变量名(不带
前缀)引用变量,引擎据此区分变量与物理列。别名. - 查询绑定:
,semantic_view(... VARIABLES <名> => <值>)
或=>
均可,绑定值必须是常量;不绑定则用默认值。=
完整示例见创建语义视图的"带查询参数(VARIABLES)的语义视图"和查询语义视图的"查询时绑定 VARIABLES"。
关系与查询限制
- 查询必须至少指定一个
、DIMENSIONS
或METRICS
,否则报FACTS
。table or view not found - semantic_view - 同一父表下多条独立一对多分支的指标(chasm trap 扇出)可以组合在同一次查询里,引擎在各自粒度分别聚合再对齐维度,不会放大。详见语义视图关系建模与聚合粒度的"多分支扇出的自动处理"。
- 跨表查询的连接和聚合粒度由指标所在表驱动,关系建模直接影响结果正确性。详见语义视图关系建模与聚合粒度。
DDL 与管理
- 支持
:可原子替换同名视图定义,无需先CREATE OR REPLACE SEMANTIC VIEW
,重放脚本天然幂等。DROP - 支持
:返回完整、可重放的SHOW CREATE SEMANTIC VIEW <视图名>
DDL(含CREATE
/TABLES
/DIMENSIONS
及METRICS
)。WITH SYNONYMS
等其他元数据不进 DDL,用enum_values
查看(注意DESC EXTENDED
/is_unique
回读值不保真,见"元数据子句")。is_time
支持ALTER SEMANTIC VIEW
、RENAME TO
、SET PROPERTIES
,但不支持直接增删维度/指标(UNSET PROPERTIES
、ADD/DROP DIMENSION
报语法错误)。需要增删维度/指标时用ADD/DROP METRIC
重放完整定义。CREATE OR REPLACE
的新名称不能带 schema 前缀(带前缀报语法错误)。RENAME TO- 没有
函数、YAML 导出;GET_DDL
/DESC SEMANTIC VIEW
命令存在但返回空,DESCRIBE SEMANTIC VIEW
(不加DESC
)也返回空。回读结构用EXTENDED
(DDL 文本)或SHOW CREATE SEMANTIC VIEW
(结构化,含全量元数据)。DESC EXTENDED
创建行为
子句必填,TABLES
和DIMENSIONS
均可选(仅METRICS
也能创建成功)。TABLES- 视图已存在时
报CREATE SEMANTIC VIEW
;用already exists
跳过,或先执行IF NOT EXISTS
保证脚本幂等。DROP SEMANTIC VIEW IF EXISTS - 外键列与被引用列数据类型必须一致,否则报错,例如:
跨表指标与粒度
外键定义了逻辑表的一对多关系:被引用方是父表(粒度更粗),引用方是子表(粒度更细)。指标的聚合可以作用于自己表的列(单层聚合),也可以对更细子表的列做双层聚合。
双层聚合 —— 父表指标对子表列先按父表粒度汇总、再聚合。例如"每个订单的明细金额之和"再求平均:
内层
SUM 把 lineitem 汇总到订单粒度,外层 AVG 再汇总到查询粒度。查询时按父表维度分组即得到正确的上卷(roll-up)结果。
恒等透传(FACTS) —— 父表指标要引用子表的列时,需先在
FACTS 子句把该列声明为逻辑事实,指标再引用这个事实。有两种可行写法:
查询时的分组规则 —— 指标可以按等于或更粗粒度的维度分组(roll-up 上卷),但不能按更细粒度的维度分组(会扇出双重计算)。例如用子表
orders 的维度去分组父表 customer 粒度的指标,引擎会拦截并给出清晰的粒度错误:
去重计数的正确列 —— 统计"去重的父实体数量"时,用子表自己的外键列而不是父表主键:
COUNT(DISTINCT orders.o_custkey) 可行;在 orders 指标里写 COUNT(DISTINCT customer.c_custkey)(父表主键)会报 cannot resolve column。两者去重结果相同,但前者无扇出。
内省命令
除
SHOW SEMANTIC VIEWS 外,还有五条命令返回结构化、每对象一行的元数据,适合 Agent 精确发现视图结构(能按什么分组、能聚合什么、表怎么关联),无需解析 DDL 文本:
DIMENSIONS、METRICS、FACTS 三者返回相同的 9 列:workspace_name、schema_name、semantic_view_name、table_name、name、data_type、synonyms、comment、access(PUBLIC/PRIVATE)。RELATIONSHIPS 和 TABLES 的列不同(见下)。
以
doc_test.emp_dept_analysis 为例,SHOW SEMANTIC DIMENSIONS 返回:
SHOW SEMANTIC RELATIONSHIPS 返回外键关系,列为 workspace_name、schema_name、semantic_view_name、relationship_name、table_name、columns、ref_table_name、ref_columns、relationship_type:
relationship_type 反映外键推断出的关系基数(一对多外键为 MANY_TO_ONE,从子表看向父表)。
SHOW SEMANTIC TABLES 返回逻辑表到物理表的映射,列为 workspace_name、schema_name、semantic_view_name、table_name、base_table、primary_key、synonyms、comment:
粒度安全过滤:FOR METRIC
SHOW SEMANTIC DIMENSIONS ... FOR METRIC <指标> 只返回可合法用于分组该指标的维度(与指标同粒度或更粗),据此可直接构造不会触发下钻报错的查询。以粒度阶梯视图 sv_grain(region→customer→orders→lineitem)为例,order_amount 是 orders 粒度的指标:
返回 region、customer、orderkey 三个维度(等于或更粗),过滤掉了更细的 lineitem 维度——因为用 lineitem 粒度分组 orders 指标会触发扇出下钻,属非法。换成最细的
line_revenue(lineitem 粒度)指标,则四个维度全部返回。
- 视图未定义某类对象时返回空行(如没有
时FACTS
返回 0 行),属正常。SHOW SEMANTIC FACTS
对象可见性:PUBLIC 与 PRIVATE
维度、指标、事实可标记为
PUBLIC(默认)或 PRIVATE。PRIVATE 对象不能被直接查询或过滤,只能被组合进其他 PUBLIC 的事实/指标——用于封装中间计算,不暴露给最终查询。
直接查询
PRIVATE 指标报错:
SHOW SEMANTIC METRICS / DIMENSIONS / FACTS 的 access 列会显示每个对象是 PUBLIC 还是 PRIVATE(见"内省命令")。
权限模型
语义视图只支持只读权限。
(或GRANT SELECT
,等同于 SELECT)可授予角色查询权限;创建者自动拥有ALL
。ALL- 不支持
/INSERT
/UPDATE
,DELETE
报GRANT INSERT ON SEMANTIC VIEW ...
。invalid action type INSERT
查看授权,返回列:SHOW GRANTS ON SEMANTIC VIEW <名称>
、granted_type
、privilege
、conditions
(值为granted_on
)、SEMANTIC_VIEW
、object_name
、granted_to
、grantee_name
、grantor_name
、grant_option
。granted_time
限制速查表
| 能力 | 状态 | 说明 / 报错 |
|---|---|---|
| 通用聚合函数(DISTINCT/STDDEV/MEDIAN/PERCENTILE/GROUP_CONCAT 等) | 支持 | 不限于 COUNT/SUM/AVG/MIN/MAX |
| 算术表达式指标(MAX-MIN、SUM/COUNT 等) | 支持 | 单独查、混查结果均正确 |
| 派生指标(同表相除 / 引用命名指标) | 支持 | 指标体内相除,或引用同表已命名指标 |
| 条件指标 FILTER (WHERE ...) | 支持 | 多个过滤指标可并列查询 |
| 双层聚合(父表聚合子表列) | 支持 | AVG(SUM(子表.列)) |
| 恒等透传 FACTS | 支持 | 父表指标引用子表列的前置声明 |
| NULL 处理 | 标准 SQL 语义 | NULL 维度单独成组;聚合跳过 NULL;零除返回 NULL |
| SYNONYMS / enum_values 回读 | 保真 | 进 DESC EXTENDED,值与创建一致 |
| is_unique / is_time 回读 | 值不保真 | 声明即回读 true,不反映实际值 |
| CREATE OR REPLACE | 支持 | 原子替换,脚本幂等 |
| SHOW CREATE SEMANTIC VIEW | 支持 | 返回可重放 DDL |
| SHOW SEMANTIC DIMENSIONS/METRICS/FACTS | 支持 | 9 列,含 access;维度支持 FOR METRIC |
| 查询参数 VARIABLES | 支持 | TABLES 后声明,查询时 绑定,含默认值 |
| PUBLIC / PRIVATE 对象可见性 | 支持 | PRIVATE 只能被组合,不能直接查 |
| 窗口函数指标(RANK/占比/累计等) | 支持 | PARTITION BY/ORDER BY 用维度限定名、同表、查询须含该维度 |
| 跨表指标相除(引用他表列) | 不支持 | 报 cannot resolve column |
| 细维度分组粗指标(下钻) | 拦截报错 | invalid dimension ... finer grain(防扇出) |
| chasm trap(兄弟分支指标组合) | 自动处理 | 各分支独立聚合再对齐维度,不放大 |
| SHOW SEMANTIC RELATIONSHIPS / TABLES | 支持 | 结构化回读外键关系、逻辑表映射 |
| ALTER 增删维度/指标 | 不支持 | 用 CREATE OR REPLACE 重放;RENAME TO 不能带 schema 前缀 |
| 仅 TABLES 创建 | 支持 | DIMENSIONS / METRICS 可选 |
| 权限 | 只读 | SELECT / ALL;无 INSERT / UPDATE / DELETE |
排错速查(按症状)
遇到报错或结果不对时,按下面的症状定位原因。
| 症状 / 报错 | 原因 | 对策 |
|---|---|---|
窗口指标报 | PARTITION BY/ORDER BY 用了物理列名或裸别名 | 改用维度限定别名,如 |
窗口指标报 | 查询未把 PARTITION BY/ORDER BY 的维度放进 DIMENSIONS | 在 的 DIMENSIONS 中带上该维度 |
创建报 (指标聚合父表列) | 指标聚合了更粗父表的列 | 只聚合自己表或更细子表的列;跨表引用子表列先用 FACTS 透传 |
创建报 | 外键列与被引用列类型不一致 | 改用类型一致的列,或显式指定引用列 |
查询报 | 用更细粒度的维度分组更粗粒度的指标(下钻) | 只用等于或更粗粒度的维度分组,或去掉该维度 |
查询报 | 没传任何 DIMENSIONS/METRICS/FACTS | 至少指定一个维度、指标或事实 |
创建报 | 视图已存在且未用替换语法 | 用 ,或加 |
查询报 | 直接查询了 PRIVATE 对象 | PRIVATE 只能被组合进 PUBLIC 对象,改查 PUBLIC 指标 |
返回空 | 没加 ,或用了 | 用 或 |
返回空 | 不支持 过滤 | 去掉 LIKE,全列后自行筛选 |
| 跨表指标数值偏大/重复 | 手写 JOIN 导致扇出双重计算 | 用语义视图自动按指标粒度聚合,不要手写 JOIN |
| 维度成员缺失(如某客户不出现) | 该成员在指标表里没有事实行 | 需要全集时直接查维度表,详见关系建模与聚合粒度 |
