语义视图能力与限制参考

本文集中说明语义视图支持的能力和当前边界,供你在设计视图或排查报错时查阅。每条能力和限制都附最小复现 SQL 和真实输出/报错。

功能概述

语义视图通过声明式定义把多表关系、维度和指标沉淀为业务语义层。指标支持通用聚合函数、算术表达式、条件聚合和窗口函数,DDL 支持

CREATE OR REPLACE
CREATE OR REPLACE
SHOW CREATE
SHOW CREATE
回读定义。仍有少数边界(窗口函数的
PARTITION BY
PARTITION BY
用维度限定名且受同表约束、跨表指标相除等),设计前先了解这些边界可以避免"创建成功但查询出错"这类问题。需要完整查询语法见查询语义视图,跨表关系的聚合粒度见语义视图关系建模与聚合粒度

指标定义能力

指标体是标准的聚合表达式,支持范围很广:

  • 通用聚合函数:不限于
    COUNT
    COUNT
    /
    SUM
    SUM
    /
    AVG
    AVG
    /
    MIN
    MIN
    /
    MAX
    MAX
    ,还包括
    COUNT(DISTINCT ...)
    COUNT(DISTINCT ...)
    SUM(DISTINCT ...)
    SUM(DISTINCT ...)
    APPROX_COUNT_DISTINCT
    APPROX_COUNT_DISTINCT
    STDDEV
    STDDEV
    VARIANCE
    VARIANCE
    MEDIAN
    MEDIAN
    PERCENTILE(col, p)
    PERCENTILE(col, p)
    GROUP_CONCAT
    GROUP_CONCAT
    ANY_VALUE
    ANY_VALUE
    等。
  • 条件聚合
    COUNT(CASE WHEN ...)
    COUNT(CASE WHEN ...)
    ,以及标准 SQL 的
    <聚合函数>(...) FILTER (WHERE <条件>)
    <聚合函数>(...) FILTER (WHERE <条件>)
    过滤指标——每个聚合的过滤条件独立生效,可在同一视图里并列定义分段 KPI 并一起查询。
  • 算术表达式指标
    MAX(col) - MIN(col)
    MAX(col) - MIN(col)
    SUM(col) / COUNT(col)
    SUM(col) / COUNT(col)
    SUM(col) * 100.0 / SUM(col)
    SUM(col) * 100.0 / SUM(col)
    这类在指标体内直接做运算是支持的,单独查询和与其他指标混查都返回正确结果。

派生指标(同表) —— 支持。同一逻辑表内既可把两个聚合的比值直接写在一个指标体里,也可引用同表已命名的其他指标做运算:

METRICS ( orders.total_sales AS SUM(orders.o_totalprice), orders.distinct_cust AS COUNT(DISTINCT orders.o_custkey), -- 写法一:直接在指标体内相除 orders.clv AS SUM(orders.o_totalprice) / COUNT(DISTINCT orders.o_custkey), -- 写法二:引用上面已命名的指标 orders.avg_val AS orders.total_sales / orders.distinct_cust )

两种写法都支持,且可组合同表任意已命名指标。

窗口函数指标 —— 支持。可在指标体内使用窗口函数(

RANK()
RANK()
/
ROW_NUMBER()
ROW_NUMBER()
等排名,或
SUM(SUM(...)) OVER (...)
SUM(SUM(...)) OVER (...)
这类聚合套窗口做占比、累计),但
PARTITION BY
PARTITION BY
/
ORDER BY
ORDER BY
有三条约束:

  • 必须引用维度的限定别名(如
    orders.region
    orders.region
    ),不能用物理列名(
    o_region
    o_region
    )或裸别名(
    region
    region
    ),否则报
    must reference a declared dimension by its alias
    must reference a declared dimension by its alias
    cannot resolve column
    cannot resolve column
  • partition/order 维度受同表约束:只能是指标所在逻辑表的维度;跨表引用父表维度(如指标在
    orders
    orders
    PARTITION BY customers.region
    PARTITION BY customers.region
    )报
    cannot resolve column
    cannot resolve column
  • 查询时该维度必须出现在
    semantic_view()
    semantic_view()
    DIMENSIONS
    DIMENSIONS
    中,否则报明确语义错。

METRICS ( -- 每个成员占其所在分区的收入比 orders.pct_of_region AS SUM(orders.o_totalprice) * 100.0 / SUM(SUM(orders.o_totalprice)) OVER (PARTITION BY orders.region) )

具体示例与实测输出见创建语义视图的"带窗口函数指标的语义视图"。

以下指标定义仍不受支持:

跨表指标相除 —— 一个指标体只能引用自己所在表的列,不能引用其他表的列。例如在

customer
customer
表的指标里写
COUNT(customer.c_custkey) / COUNT(nation.n_nationkey)
COUNT(customer.c_custkey) / COUNT(nation.n_nationkey)
,会因引用不到
nation
nation
的列而报
cannot resolve column 'n_nationkey'
cannot resolve column 'n_nationkey'
。派生指标只能组合同表的聚合(见上文"派生指标")。要聚合更细子表的列,用双层聚合或
FACTS
FACTS
透传(见下文"跨表指标与粒度")。

NULL 值处理

语义视图的 NULL 处理遵循标准 SQL 语义,几个容易困惑的点:

  • NULL 维度值单独成组,不会被丢弃。按含 NULL 的维度分组时,所有 NULL 行聚成一个
    NULL
    NULL
    分组参与聚合。
  • 聚合函数跳过 NULL
    SUM
    SUM
    /
    AVG
    AVG
    /
    MIN
    MIN
    /
    MAX
    MAX
    /
    COUNT(<列>)
    COUNT(<列>)
    都忽略 NULL 值。因此
    AVG
    AVG
    的分母是非 NULL 行数,不是总行数;
    COUNT(<列>)
    COUNT(<列>)
    只数非 NULL,而
    COUNT(<主键>)
    COUNT(<主键>)
    数全部行——同一组里这两个值可能不同。
  • 空结果集:对空表或过滤后无行的分组,
    COUNT
    COUNT
    返回
    0
    0
    SUM
    SUM
    /
    AVG
    AVG
    等返回
    NULL
    NULL
    (不报错)。
  • 除法零除返回 NULL:派生指标里若分母算出
    0
    0
    (如
    SUM(x) / (COUNT(a) - COUNT(b))
    SUM(x) / (COUNT(a) - COUNT(b))
    恰好为 0),该指标返回
    NULL
    NULL
    而不是报错。因此无需为零除额外加保护,但要注意结果中的
    NULL
    NULL
    可能来自零除而非缺数据。

元数据子句

维度元数据子句在

CREATE
CREATE
时的书写顺序是固定的:
WITH SYNONYMS
WITH SYNONYMS
必须写在
is_unique
is_unique
/
is_time
is_time
/
enum_values
enum_values
之前,否则报语法错误(
Syntax error at or near 'WITH'
Syntax error at or near 'WITH'
)。

这些子句会持久化,可通过

DESC EXTENDED
DESC EXTENDED
回读,但回读保真度不一:

  • WITH SYNONYMS
    WITH SYNONYMS
    (可多个)、
    enum_values
    enum_values
    —— 回读值与创建值一致。
  • is_unique
    is_unique
    is_time
    is_time
    —— 只反映"是否声明过",不反映设定的值:只要在
    CREATE
    CREATE
    时写了该子句,
    DESC EXTENDED
    DESC EXTENDED
    一律回读为
    true
    true
    (即便创建时写的是
    = false
    = false
    );完全不写该子句时,
    DESC EXTENDED
    DESC EXTENDED
    中不出现对应行。因此不能依赖
    DESC EXTENDED
    DESC EXTENDED
    判断
    is_unique
    is_unique
    /
    is_time
    is_time
    的真实取值,应以创建脚本为准。
  • SHOW CREATE SEMANTIC VIEW
    SHOW CREATE SEMANTIC VIEW
    回读的 DDL 只含
    WITH SYNONYMS
    WITH SYNONYMS
    ,不含
    is_unique
    is_unique
    /
    is_time
    is_time
    /
    enum_values
    enum_values
    ;需要看这些用
    DESC EXTENDED
    DESC EXTENDED

需要过滤时,用

FILTER (WHERE ...)
FILTER (WHERE ...)
条件聚合指标(见"指标定义能力"),或在
semantic_view()
semantic_view()
外层用
WHERE
WHERE
+ 维度短名实现。

关系与查询限制

  • 查询必须至少指定一个
    DIMENSIONS
    DIMENSIONS
    METRICS
    METRICS
    FACTS
    FACTS
    ,否则报
    table or view not found - semantic_view
    table or view not found - semantic_view
  • 不能在同一次查询中组合来自两个无直接关系路径的分支的指标(chasm trap),会报
    No relationship found for table <表名>
    No relationship found for table <表名>
  • 跨表查询的连接和聚合粒度由指标所在表驱动,关系建模直接影响结果正确性。详见语义视图关系建模与聚合粒度

DDL 与管理

  • 支持
    CREATE OR REPLACE SEMANTIC VIEW
    CREATE OR REPLACE SEMANTIC VIEW
    :可原子替换同名视图定义,无需先
    DROP
    DROP
    ,重放脚本天然幂等。
  • 支持
    SHOW CREATE SEMANTIC VIEW <视图名>
    SHOW CREATE SEMANTIC VIEW <视图名>
    :返回完整、可重放的
    CREATE
    CREATE
    DDL(含
    TABLES
    TABLES
    /
    DIMENSIONS
    DIMENSIONS
    /
    METRICS
    METRICS
    WITH SYNONYMS
    WITH SYNONYMS
    )。
    enum_values
    enum_values
    等其他元数据不进 DDL,用
    DESC EXTENDED
    DESC EXTENDED
    查看(注意
    is_unique
    is_unique
    /
    is_time
    is_time
    回读值不保真,见"元数据子句")。
  • ALTER SEMANTIC VIEW
    ALTER SEMANTIC VIEW
    支持
    RENAME TO
    RENAME TO
    SET PROPERTIES
    SET PROPERTIES
    UNSET PROPERTIES
    UNSET PROPERTIES
    ,但不支持直接增删维度/指标(
    ADD/DROP DIMENSION
    ADD/DROP DIMENSION
    ADD/DROP METRIC
    ADD/DROP METRIC
    报语法错误)。需要增删维度/指标时用
    CREATE OR REPLACE
    CREATE OR REPLACE
    重放完整定义。
    RENAME TO
    RENAME TO
    的新名称不能带 schema 前缀(带前缀报语法错误)。
  • 没有
    GET_DDL
    GET_DDL
    函数、YAML 导出;
    DESC SEMANTIC VIEW
    DESC SEMANTIC VIEW
    /
    DESCRIBE SEMANTIC VIEW
    DESCRIBE SEMANTIC VIEW
    命令存在但返回空,
    DESC
    DESC
    (不加
    EXTENDED
    EXTENDED
    )也返回空。回读结构用
    SHOW CREATE SEMANTIC VIEW
    SHOW CREATE SEMANTIC VIEW
    (DDL 文本)或
    DESC EXTENDED
    DESC EXTENDED
    (结构化,含全量元数据)。

创建行为

  • TABLES
    TABLES
    子句必填,
    DIMENSIONS
    DIMENSIONS
    METRICS
    METRICS
    均可选(仅
    TABLES
    TABLES
    也能创建成功)。
  • 视图已存在时
    CREATE SEMANTIC VIEW
    CREATE SEMANTIC VIEW
    already exists
    already exists
    ;用
    IF NOT EXISTS
    IF NOT EXISTS
    跳过,或先执行
    DROP SEMANTIC VIEW IF EXISTS
    DROP SEMANTIC VIEW IF EXISTS
    保证脚本幂等。
  • 外键列与被引用列数据类型必须一致,否则报错,例如:

CZLH-42000: type int of foreign key column o_custkey does not match type string of referenced column c_name

跨表指标与粒度

外键定义了逻辑表的一对多关系:被引用方是父表(粒度更粗),引用方是子表(粒度更细)。指标的聚合可以作用于自己表的列(单层聚合),也可以对更细子表的列做双层聚合

双层聚合 —— 父表指标对子表列先按父表粒度汇总、再聚合。例如"每个订单的明细金额之和"再求平均:

METRICS ( orders.avg_line AS AVG(SUM(lineitem.l_price)) )

内层

SUM
SUM
lineitem
lineitem
汇总到订单粒度,外层
AVG
AVG
再汇总到查询粒度。查询时按父表维度分组即得到正确的上卷(roll-up)结果。

恒等透传(FACTS) —— 父表指标要引用子表的列时,需先在

FACTS
FACTS
子句把该列声明为逻辑事实,指标再引用这个事实。有两种可行写法:

-- 写法一:组合聚合定义在 FACTS 内,查询用 FACTS 关键字 FACTS ( orders.o_orderkey AS o_orderkey, customer.order_count AS COUNT(orders.o_orderkey) ) -- 查询:SELECT * FROM semantic_view(sv, FACTS customer.order_count) -- 写法二:FACTS 只做透传(别名与物理列不同名),组合聚合放 METRICS FACTS (orders.order_id AS o_orderkey) METRICS (customer.order_count AS COUNT(orders.order_id)) -- 查询:SELECT * FROM semantic_view(sv, METRICS customer.order_count)

查询时的分组规则 —— 指标可以按等于或更粗粒度的维度分组(roll-up 上卷),但不能按更细粒度的维度分组(会扇出双重计算)。例如用子表

orders
orders
的维度去分组父表
customer
customer
粒度的指标,引擎会拦截并给出清晰的粒度错误:

CZLH-42000: invalid dimension 'orders.okey': its logical table 'orders' has a finer grain than metric 'customer.custcnt' ... A metric can only be grouped by dimensions at an equal or coarser grain, otherwise it would be fanned out and double-counted.

去重计数的正确列 —— 统计"去重的父实体数量"时,用子表自己的外键列而不是父表主键:

COUNT(DISTINCT orders.o_custkey)
COUNT(DISTINCT orders.o_custkey)
可行;在
orders
orders
指标里写
COUNT(DISTINCT customer.c_custkey)
COUNT(DISTINCT customer.c_custkey)
(父表主键)会报
cannot resolve column
cannot resolve column
。两者去重结果相同,但前者无扇出。

内省命令

SHOW SEMANTIC VIEWS
SHOW SEMANTIC VIEWS
外,还有三条命令返回结构化、每对象一行的元数据,适合 Agent 精确发现"能按什么分组、能聚合什么",无需解析 DDL 文本:

SHOW SEMANTIC DIMENSIONS IN <视图> [ FOR METRIC <指标> ] SHOW SEMANTIC METRICS IN <视图> SHOW SEMANTIC FACTS IN <视图>

三者返回相同的 9 列:

workspace_name
workspace_name
schema_name
schema_name
semantic_view_name
semantic_view_name
table_name
table_name
name
name
data_type
data_type
synonyms
synonyms
comment
comment
access
access
PUBLIC
PUBLIC
/
PRIVATE
PRIVATE
)。

  • 维度形式加
    FOR METRIC <指标>
    FOR METRIC <指标>
    只返回可合法用于分组该指标的维度(等于或更粗粒度且相关),据此可直接构造粒度安全的
    semantic_view(...)
    semantic_view(...)
    查询。
  • 视图未定义某类对象时返回空行(如没有维度时
    SHOW SEMANTIC DIMENSIONS
    SHOW SEMANTIC DIMENSIONS
    返回 0 行),属正常。

对象可见性:PUBLIC 与 PRIVATE

维度、指标、事实可标记为

PUBLIC
PUBLIC
(默认)或
PRIVATE
PRIVATE
PRIVATE
PRIVATE
对象不能被直接查询或过滤,只能被组合进其他
PUBLIC
PUBLIC
的事实/指标——用于封装中间计算,不暴露给最终查询。

METRICS ( orders.pub_total AS SUM(o_totalprice), -- 默认 PUBLIC PRIVATE orders.raw_cnt AS COUNT(o_orderkey) -- PRIVATE 放在对象名前 )

直接查询

PRIVATE
PRIVATE
指标报错:

CZLH-42000: METRICS 'orders.raw_cnt' is PRIVATE and cannot be selected or filtered directly; it may only be composed into a PUBLIC fact/metric

SHOW SEMANTIC METRICS
SHOW SEMANTIC METRICS
/
DIMENSIONS
DIMENSIONS
/
FACTS
FACTS
access
access
列会显示每个对象是
PUBLIC
PUBLIC
还是
PRIVATE
PRIVATE
(见"内省命令")。

权限模型

语义视图只支持只读权限。

  • GRANT SELECT
    GRANT SELECT
    (或
    ALL
    ALL
    ,等同于 SELECT)可授予角色查询权限;创建者自动拥有
    ALL
    ALL
  • 不支持
    INSERT
    INSERT
    /
    UPDATE
    UPDATE
    /
    DELETE
    DELETE
    GRANT INSERT ON SEMANTIC VIEW ...
    GRANT INSERT ON SEMANTIC VIEW ...
    invalid action type INSERT
    invalid action type INSERT
  • SHOW GRANTS ON SEMANTIC VIEW <名称>
    SHOW GRANTS ON SEMANTIC VIEW <名称>
    查看授权,返回列:
    granted_type
    granted_type
    privilege
    privilege
    conditions
    conditions
    granted_on
    granted_on
    (值为
    SEMANTIC_VIEW
    SEMANTIC_VIEW
    )、
    object_name
    object_name
    granted_to
    granted_to
    grantee_name
    grantee_name
    grantor_name
    grantor_name
    grant_option
    grant_option
    granted_time
    granted_time

GRANT SELECT ON SEMANTIC VIEW doc_test.emp_dept_analysis TO ROLE workspace_analyst; REVOKE SELECT ON SEMANTIC VIEW doc_test.emp_dept_analysis FROM ROLE workspace_analyst;

限制速查表

能力状态说明 / 报错
通用聚合函数(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
PUBLIC / PRIVATE 对象可见性支持PRIVATE 只能被组合,不能直接查
窗口函数指标(RANK/占比/累计等)支持PARTITION BY/ORDER BY 用维度限定名、同表、查询须含该维度
跨表指标相除(引用他表列)不支持报 cannot resolve column
细维度分组粗指标(下钻)拦截报错invalid dimension ... finer grain(防扇出)
chasm trap(兄弟分支指标组合)拦截报错No relationship found for table …
ALTER 增删维度/指标不支持用 CREATE OR REPLACE 重放;RENAME TO 不能带 schema 前缀
仅 TABLES 创建支持DIMENSIONS / METRICS 可选
权限只读SELECT / ALL;无 INSERT / UPDATE / DELETE

排错速查(按症状)

遇到报错或结果不对时,按下面的症状定位原因。

症状 / 报错原因对策
窗口指标报
must reference a declared dimension by its alias
must reference a declared dimension by its alias
PARTITION BY/ORDER BY 用了物理列名或裸别名改用维度限定别名,如
orders.region
orders.region
窗口指标报
must also be requested as a dimension
must also be requested as a dimension
查询未把 PARTITION BY/ORDER BY 的维度放进 DIMENSIONS
semantic_view()
semantic_view()
的 DIMENSIONS 中带上该维度
创建报
cannot resolve column
cannot resolve column
(指标聚合父表列)
指标聚合了更粗父表的列只聚合自己表或更细子表的列;跨表引用子表列先用 FACTS 透传
创建报
type ... does not match
type ... does not match
外键列与被引用列类型不一致改用类型一致的列,或显式指定引用列
查询报
invalid dimension ... finer grain
invalid dimension ... finer grain
用更细粒度的维度分组更粗粒度的指标(下钻)只用等于或更粗粒度的维度分组,或去掉该维度
查询报
No relationship found for table
No relationship found for table
组合了两个无直接关系路径的分支指标(chasm trap)拆成多次查询,每次只取一条关系链上的指标
查询报
table or view not found - semantic_view
table or view not found - semantic_view
semantic_view()
semantic_view()
没传任何 DIMENSIONS/METRICS/FACTS
至少指定一个维度、指标或事实
创建报
already exists
already exists
视图已存在且未用替换语法
CREATE OR REPLACE
CREATE OR REPLACE
,或加
IF NOT EXISTS
IF NOT EXISTS
查询报
is PRIVATE and cannot be selected
is PRIVATE and cannot be selected
直接查询了 PRIVATE 对象PRIVATE 只能被组合进 PUBLIC 对象,改查 PUBLIC 指标
DESC
DESC
返回空
没加
EXTENDED
EXTENDED
,或用了
DESC SEMANTIC VIEW
DESC SEMANTIC VIEW
DESC EXTENDED <视图名>
DESC EXTENDED <视图名>
SHOW CREATE SEMANTIC VIEW
SHOW CREATE SEMANTIC VIEW
SHOW SEMANTIC VIEWS LIKE
SHOW SEMANTIC VIEWS LIKE
返回空
SHOW
SHOW
不支持
LIKE
LIKE
过滤
去掉 LIKE,全列后自行筛选
跨表指标数值偏大/重复手写 JOIN 导致扇出双重计算用语义视图自动按指标粒度聚合,不要手写 JOIN
维度成员缺失(如某客户不出现)该成员在指标表里没有事实行需要全集时直接查维度表,详见关系建模与聚合粒度

相关文档

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询