创建语义视图

语法

CREATE [ OR REPLACE ] SEMANTIC VIEW [ IF NOT EXISTS ] <视图名称> TABLES ( <逻辑表定义> [ , ... ] ) [ RELATIONSHIPS ( <关系定义> [ , ... ] ) ] [ VARIABLES ( <变量定义> [ , ... ] ) ] [ FACTS ( <事实定义> [ , ... ] ) ] [ DIMENSIONS ( <维度定义> [ , ... ] ) ] [ METRICS ( <指标定义> [ , ... ] ) ] [ COMMENT = '<视图说明>' ] ;

各子句的定义语法如下:

逻辑表定义

<表别名> AS <架构名>.<物理表名> PRIMARY KEY ( <列名> [ , ... ] ) [ FOREIGN KEY ( <列名> ) REFERENCES <其他逻辑表别名> [ ( <引用列名> ) ] ] [ WITH SYNONYMS ( '<同义词>' [ , ... ] ) ] [ COMMENT = '<说明>' ]

关系定义

<引用表别名> ( <外键列> [ , ... ] ) REFERENCES <被引用表别名> [ ( <引用列> [ , ... ] ) ]

RELATIONSHIPS
RELATIONSHIPS
是声明外键关系的独立顶层子句,与写在逻辑表内的内联
FOREIGN KEY
FOREIGN KEY
等价——同一份关系既可内联,也可集中写在
RELATIONSHIPS
RELATIONSHIPS
里。回读(
SHOW CREATE SEMANTIC VIEW
SHOW CREATE SEMANTIC VIEW
/
DESC EXTENDED
DESC EXTENDED
)时统一规范化为
RELATIONSHIPS
RELATIONSHIPS
形式。外键列与被引用列的数据类型必须一致,列名不同时需显式写出引用列。复合外键在括号内按顺序列出多列。

变量定义

<变量名> <数据类型> [ { DEFAULT | = } <默认值> ] [ COMMENT = '<说明>' ]

VARIABLES
VARIABLES
声明查询参数:维度、指标表达式里引用这个变量名,查询时可用
semantic_view()
semantic_view()
VARIABLES
VARIABLES
子句为它绑定值,实现同一视图按不同阈值/口径取数。
DEFAULT
DEFAULT
=
=
等价(都持久化为
DEFAULT
DEFAULT
);不写默认值的变量,只要被维度/指标引用,查询时就必须绑定。绑定方式见查询语义视图的"查询时绑定 VARIABLES"。

事实定义

[ PRIVATE ] <逻辑表别名>.<事实名> AS { <列表达式> | <聚合表达式> }

FACTS
FACTS
声明逻辑事实,主要用于父表指标引用子表的列:父表指标不能直接聚合子表列,需先在
FACTS
FACTS
里把子表列声明为事实(恒等透传),指标再引用这个事实。详见能力与限制参考的"跨表指标与粒度"。

维度定义

[ PRIVATE ] { <逻辑表别名>.<维度名> | <维度名> } AS <表达式> [ WITH SYNONYMS = ( '<同义词>' [ , ... ] ) ] [ is_unique = { true | false } ] [ is_time = { true | false } ] [ enum_values = [ <值1>, <值2>, ... ] ] [ COMMENT = '<说明>' ]

指标定义

[ PRIVATE ] <逻辑表别名>.<指标名> AS <聚合表达式> [ COMMENT = '<说明>' ]

PRIVATE
PRIVATE
修饰符(默认
PUBLIC
PUBLIC
)标记该维度/指标/事实只能被组合进其他
PUBLIC
PUBLIC
对象,不能被直接查询或过滤,用于封装中间计算。详见能力与限制参考的"对象可见性"。

参数说明

逻辑表参数

参数说明
<表别名> AS <架构名>.<物理表名>
<表别名> AS <架构名>.<物理表名>
为物理表指定逻辑别名,后续维度、指标、外键定义均使用此别名
PRIMARY KEY ( <列名> )
PRIMARY KEY ( <列名> )
指定主键列,用于确定表间关系类型
FOREIGN KEY ( <列名> ) REFERENCES <别名> [ ( <引用列名> ) ]
FOREIGN KEY ( <列名> ) REFERENCES <别名> [ ( <引用列名> ) ]
定义外键关系。当外键列与被引用表主键列名不同时,需显式指定引用列名。外键列与引用列数据类型必须一致,否则创建报错
WITH SYNONYMS ( '<同义词>' )
WITH SYNONYMS ( '<同义词>' )
为逻辑表定义同义词,增强可发现性
COMMENT = '<说明>'
COMMENT = '<说明>'
逻辑表描述

维度参数

参数说明
is_unique = true
is_unique = true
声明该维度值唯一,如客户名称(声明性标注,当前无 SQL 层效果)
is_time = true
is_time = true
声明该维度为时间类型,如订单日期(声明性标注,当前无 SQL 层效果)
enum_values = [...]
enum_values = [...]
声明维度的取值范围(声明性标注,不做输入校验,越界值照常返回)
WITH SYNONYMS = (...)
WITH SYNONYMS = (...)
为维度定义同义词,支持多种业务术语引用同一维度

事实参数

参数说明
<别名>.<事实名> AS <列表达式>
<别名>.<事实名> AS <列表达式>
恒等透传:把子表的列声明为逻辑事实(别名可与物理列不同名),供父表指标引用。父表指标不能直接聚合子表列,透传后即可引用
<别名>.<事实名> AS <聚合表达式>
<别名>.<事实名> AS <聚合表达式>
FACTS
FACTS
内直接定义组合聚合(如
COUNT(...)
COUNT(...)
),查询时用
FACTS
FACTS
关键字选取
PRIVATE
PRIVATE
标记事实只能被组合进其他
PUBLIC
PUBLIC
对象,不能被直接查询

变量参数

参数说明
<变量名> <数据类型>
<变量名> <数据类型>
声明一个查询参数(如
min_amount decimal(12,2)
min_amount decimal(12,2)
)。维度/指标表达式用裸变量名引用它(区别于
别名.列
别名.列
形式的物理列)。不带默认值时,被引用就必须在查询时绑定,否则报错
DEFAULT <默认值>
DEFAULT <默认值>
/
= <默认值>
= <默认值>
指定默认值,查询不绑定时用它。两种写法等价,均持久化为
DEFAULT
DEFAULT
。默认值必须是常量
COMMENT = '<说明>'
COMMENT = '<说明>'
变量描述

可见性参数

参数说明
PUBLIC
PUBLIC
(默认)
维度/指标/事实可被直接查询和过滤
PRIVATE
PRIVATE
只能被组合进其他
PUBLIC
PUBLIC
对象,直接查询报
is PRIVATE and cannot be selected or filtered directly
is PRIVATE and cannot be selected or filtered directly
。用于封装中间计算,不暴露给最终查询

指标聚合函数

支持

  • 通用聚合函数,不限于
    COUNT
    COUNT
    /
    SUM
    SUM
    /
    AVG
    AVG
    /
    MIN
    MIN
    /
    MAX
    MAX
    ,还包括
    COUNT(DISTINCT ...)
    COUNT(DISTINCT ...)
    APPROX_COUNT_DISTINCT
    APPROX_COUNT_DISTINCT
    STDDEV
    STDDEV
    VARIANCE
    VARIANCE
    MEDIAN
    MEDIAN
    PERCENTILE
    PERCENTILE
    GROUP_CONCAT
    GROUP_CONCAT
    等。
  • 条件聚合,如
    COUNT(CASE WHEN col = value THEN 1 END)
    COUNT(CASE WHEN col = value THEN 1 END)
    ,以及
    <聚合函数>(...) FILTER (WHERE <条件>)
    <聚合函数>(...) FILTER (WHERE <条件>)
  • 算术表达式指标:
    MAX(col) - MIN(col)
    MAX(col) - MIN(col)
    SUM(col) / COUNT(col)
    SUM(col) / COUNT(col)
    等,可直接写在指标体内。
  • 派生指标:同一逻辑表内引用其他已命名指标做运算,如
    emps.avg AS emps.total_salary / emps.total_employees
    emps.avg AS emps.total_salary / emps.total_employees
  • 窗口函数指标:
    RANK()
    RANK()
    /
    ROW_NUMBER()
    ROW_NUMBER()
    等排名,或
    SUM(SUM(...)) OVER (...)
    SUM(SUM(...)) OVER (...)
    这类聚合套窗口做占比、累计(示例见下方"带窗口函数指标的语义视图")。
    PARTITION BY
    PARTITION BY
    /
    ORDER BY
    ORDER BY
    须引用维度的限定别名(如
    orders.region
    orders.region
    ),受同表约束,且查询时该维度须出现在
    DIMENSIONS
    DIMENSIONS
    中。

不支持

  • 跨表指标相除:指标体只能引用自己所在表(及更细子表)的列,引用无关表的列报
    cannot resolve column
    cannot resolve column
    。跨表的复合计算请放到
    semantic_view()
    semantic_view()
    查询的外层 SQL 中完成。

使用说明

  • TABLES
    TABLES
    子句是必须的,不可省略。
    RELATIONSHIPS
    RELATIONSHIPS
    VARIABLES
    VARIABLES
    FACTS
    FACTS
    DIMENSIONS
    DIMENSIONS
    METRICS
    METRICS
    均为可选,但出现时必须按
    RELATIONSHIPS → VARIABLES → FACTS → DIMENSIONS → METRICS
    RELATIONSHIPS → VARIABLES → FACTS → DIMENSIONS → METRICS
    的顺序书写。
  • CREATE OR REPLACE SEMANTIC VIEW
    CREATE OR REPLACE SEMANTIC VIEW
    可原子替换同名视图定义,无需先
    DROP
    DROP
    ,适合改结构时重放完整定义。
  • 被外键引用的逻辑表必须在
    TABLES
    TABLES
    子句中先于引用方定义。
  • 视图已存在时
    CREATE SEMANTIC VIEW
    CREATE SEMANTIC VIEW
    报错,建议先执行
    DROP SEMANTIC VIEW IF EXISTS
    DROP SEMANTIC VIEW IF EXISTS
  • 维度支持表达式(计算维度),如
    YEAR(hire_date)
    YEAR(hire_date)
    ,查询结果返回整数类型。
  • 维度和指标命名支持限定名称
    alias.name
    alias.name
    )和短名称
    name
    name
    )两种形式,名称唯一时两者等效。
  • WITH SYNONYMS
    WITH SYNONYMS
    is_unique
    is_unique
    is_time
    is_time
    enum_values
    enum_values
    这些维度元数据子句会持久化并可通过
    DESC EXTENDED
    DESC EXTENDED
    回读(其中
    synonyms
    synonyms
    enum_values
    enum_values
    值保真;
    is_unique
    is_unique
    is_time
    is_time
    只反映是否声明过,写了即回读
    true
    true
    )。它们主要面向上层 AI/元数据工具,在纯 SQL 查询链路里不影响结果。
  • 需要过滤时有三种方式:① 用
    FILTER (WHERE ...)
    FILTER (WHERE ...)
    条件聚合指标,把过滤口径持久化进视图定义(见下方示例);② 在
    semantic_view()
    semantic_view()
    内部用结尾
    WHERE
    WHERE
    子句过滤维度(排在
    DIMENSIONS
    DIMENSIONS
    /
    METRICS
    METRICS
    /
    FACTS
    FACTS
    之后、
    VARIABLES
    VARIABLES
    之前,维度限定名或短名均可);③ 在
    semantic_view()
    semantic_view()
    外层
    WHERE
    WHERE
    过滤,此处只能用维度短名(写
    emps.department
    emps.department
    会报
    cannot resolve column
    cannot resolve column
    )。方式 ② ③ 的查询语法和示例见查询语义视图

示例

前置准备

本章节多篇文档(查询语义视图高级查询用法与 AI 功能集成等)的示例都基于下面这套

doc_test.employees
doc_test.employees
doc_test.departments
doc_test.departments
表,先建表并插入数据:

CREATE TABLE doc_test.departments ( dept_id INT, dept_name STRING, manager STRING ); CREATE TABLE doc_test.employees ( id INT, name STRING, dept STRING, salary DECIMAL(12,2), hire_date DATE, is_active BOOLEAN ); INSERT INTO doc_test.departments VALUES (1, 'Engineering', 'Alice'), (2, 'Marketing', 'Bob'), (3, 'HR', 'Carol'); INSERT INTO doc_test.employees VALUES (1, 'Emp_A', 'Engineering', 130000, DATE'2019-01-01', true), (2, 'Emp_B', 'Engineering', 100000, DATE'2020-01-01', true), (3, 'Emp_C', 'Marketing', 95000, DATE'2021-01-01', true), (4, 'Emp_D', 'Marketing', 90000, DATE'2022-01-01', true), (5, 'Emp_E', 'HR', 80000, DATE'2023-01-01', true);

数据特征:Engineering 2 人(薪资 130000、100000,均值 115000)、Marketing 2 人(95000、90000,均值 92500)、HR 1 人(80000);5 人分别入职于 2019–2023 年。后续查询示例的输出均基于这套数据。

基础示例:单表语义视图

基于上面的前置数据创建语义视图:

DROP SEMANTIC VIEW IF EXISTS doc_test.emp_dept_analysis; CREATE SEMANTIC VIEW doc_test.emp_dept_analysis TABLES ( depts AS doc_test.departments PRIMARY KEY (dept_name), emps AS doc_test.employees PRIMARY KEY (id) FOREIGN KEY (dept) REFERENCES depts (dept_name) ) DIMENSIONS ( emps.employee_name AS emps.name WITH SYNONYMS = ('员工姓名', 'staff name') is_unique = true COMMENT = '员工姓名', emps.department AS emps.dept COMMENT = '所在部门', emps.hire_year AS YEAR(emps.hire_date) is_time = true COMMENT = '入职年份', depts.manager_name AS depts.manager COMMENT = '部门经理' ) METRICS ( emps.total_employees AS COUNT(emps.id) COMMENT = '员工总数', emps.avg_salary AS AVG(emps.salary) COMMENT = '平均薪资', emps.max_salary AS MAX(emps.salary) COMMENT = '最高薪资' ) COMMENT = '员工部门分析语义视图';

说明:

  • depts
    depts
    emps
    emps
    是逻辑表别名,物理表分别是
    doc_test.departments
    doc_test.departments
    doc_test.employees
    doc_test.employees
  • FOREIGN KEY (dept) REFERENCES depts (dept_name)
    FOREIGN KEY (dept) REFERENCES depts (dept_name)
    emps.dept
    emps.dept
    (string)关联
    depts.dept_name
    depts.dept_name
    (string),类型一致
  • hire_year
    hire_year
    是计算维度,通过
    YEAR()
    YEAR()
    表达式从日期列派生

带维度元数据的语义视图

以下示例展示了

is_unique
is_unique
is_time
is_time
enum_values
enum_values
等维度元数据,以及
WITH SYNONYMS
WITH SYNONYMS
子句的写法。这些元数据子句的回读行为见上方使用说明。前置数据:

CREATE TABLE doc_test.doc_meta_cust (c_custkey INT, c_name STRING); CREATE TABLE doc_test.doc_meta_ord ( o_orderkey INT, o_custkey INT, o_totalprice DECIMAL(12,2), o_orderdate DATE ); INSERT INTO doc_test.doc_meta_cust VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Carol'); INSERT INTO doc_test.doc_meta_ord VALUES (101, 1, 250.00, DATE'2025-01-15'), (102, 1, 150.00, DATE'2025-06-20'), (103, 2, 300.00, DATE'2025-06-05'), (104, 3, 500.00, DATE'2025-12-10');

DROP SEMANTIC VIEW IF EXISTS doc_test.sv_metadata; CREATE SEMANTIC VIEW doc_test.sv_metadata TABLES ( customers AS doc_test.doc_meta_cust PRIMARY KEY (c_custkey) COMMENT = '客户主表', orders AS doc_test.doc_meta_ord PRIMARY KEY (o_orderkey) FOREIGN KEY (o_custkey) REFERENCES customers WITH SYNONYMS ('sales orders') COMMENT = '销售订单表' ) DIMENSIONS ( customers.customer_name AS customers.c_name WITH SYNONYMS = ('客户名称', 'customer name') is_unique = true COMMENT = '客户名称', orders.order_date AS orders.o_orderdate is_time = true enum_values = [date'2025-01-01', date'2025-06-01', date'2025-12-01'] COMMENT = '下单日期', orders.order_year AS YEAR(orders.o_orderdate) COMMENT = '下单年份' ) METRICS ( customers.customer_count AS COUNT(customers.c_custkey) COMMENT = '客户数', orders.order_average_value AS AVG(orders.o_totalprice) COMMENT = '平均订单金额' ) COMMENT = '收入分析语义视图';

DESC EXTENDED doc_test.sv_metadata
DESC EXTENDED doc_test.sv_metadata
回读时,元数据均保真:
customer_name
customer_name
synonyms
synonyms
客户名称,customer name
客户名称,customer name
is_unique
is_unique
true
true
order_date
order_date
is_time
is_time
true
true
enum_values
enum_values
2025-01-01,2025-06-01,2025-12-01
2025-01-01,2025-06-01,2025-12-01
(date 字面量按日期值回读)。

带 FACTS 的语义视图(父表引用子表列)

父表(

customer
customer
)的指标要基于子表(
orders
orders
)的列聚合时,直接在指标里写
COUNT(orders.o_orderkey)
COUNT(orders.o_orderkey)
会因粒度不匹配失败。先在
FACTS
FACTS
里把子表列透传为逻辑事实,指标再引用这个事实。前置数据:

CREATE TABLE doc_test.fct_cust (c_custkey INT, c_name STRING); CREATE TABLE doc_test.fct_ord (o_orderkey INT, o_custkey INT, o_totalprice DECIMAL(12,2)); INSERT INTO doc_test.fct_cust VALUES (1, 'Alice'), (2, 'Bob'); INSERT INTO doc_test.fct_ord VALUES (101, 1, 250.00), (102, 1, 150.00), (103, 2, 300.00);

CREATE SEMANTIC VIEW doc_test.sv_facts TABLES ( customer AS doc_test.fct_cust PRIMARY KEY (c_custkey), orders AS doc_test.fct_ord PRIMARY KEY (o_orderkey) FOREIGN KEY (o_custkey) REFERENCES customer ) FACTS ( orders.order_id AS o_orderkey -- 透传子表列,别名与物理列不同名 ) DIMENSIONS ( customer.cust_name AS c_name ) METRICS ( customer.order_count AS COUNT(orders.order_id) -- 父表指标引用透传的事实 );

按客户名查询订单数,得到正确的上卷结果(Alice 2 笔、Bob 1 笔)。FACTS 的两种写法、双层聚合和粒度规则详见能力与限制参考的"跨表指标与粒度"。

带查询参数(VARIABLES)的语义视图

VARIABLES
VARIABLES
声明查询参数:把维度/指标里的阈值、口径抽成一个命名变量,查询时按需绑定不同的值,同一视图适配多套口径,无需为每个阈值单独建视图。下例把"销售额高低分界线"定义成变量
min_amount
min_amount
(默认 1000),维度
sale_category
sale_category
用它把销售额分成 HIGH / LOW。前置数据:

CREATE TABLE doc_test.doc_var_sales ( sale_id INT, amount DECIMAL(12,2) ); INSERT INTO doc_test.doc_var_sales VALUES (1, 500.00), (2, 1500.00), (3, 2500.00);

CREATE OR REPLACE SEMANTIC VIEW doc_test.sv_variables TABLES ( sales AS doc_test.doc_var_sales PRIMARY KEY (sale_id) ) VARIABLES ( min_amount DECIMAL(12,2) DEFAULT 1000.00 COMMENT 'HIGH/LOW 阈值' ) DIMENSIONS ( sales.sale_category AS CASE WHEN sales.amount >= min_amount THEN 'HIGH' ELSE 'LOW' END ) METRICS ( sales.total_sales AS SUM(sales.amount) );

维度表达式里的

min_amount
min_amount
是裸变量名(不带
别名.
别名.
前缀),引擎据此识别为变量而非物理列。不绑定时用默认值 1000:
amount >= 1000
amount >= 1000
的记录(1500、2500)归 HIGH,合计 4000;其余(500)归 LOW。查询时绑定其它阈值即可切换分界线,绑定语法见查询语义视图的"查询时绑定 VARIABLES"。

带条件聚合的语义视图(分段 KPI)

同一个度量常需要按不同口径拆分——总收入、仅未完成订单收入、仅已完成订单收入。用

<聚合函数>(...) FILTER (WHERE <条件>)
<聚合函数>(...) FILTER (WHERE <条件>)
把每个口径定义成独立指标,每个指标的过滤条件互相独立,可在同一次查询里并列取用。前置数据:

CREATE TABLE doc_test.doc_filt_orders ( o_orderkey INT, o_region STRING, o_totalprice DECIMAL(12,2), o_status STRING ); INSERT INTO doc_test.doc_filt_orders VALUES (101, 'East', 250.00, 'O'), (102, 'East', 150.00, 'F'), (103, 'East', 300.00, 'O'), (104, 'West', 500.00, 'F'), (105, 'West', 200.00, 'O');

CREATE SEMANTIC VIEW doc_test.sv_conditional TABLES ( orders AS doc_test.doc_filt_orders PRIMARY KEY (o_orderkey) ) DIMENSIONS ( orders.region AS orders.o_region ) METRICS ( orders.total_revenue AS SUM(orders.o_totalprice) COMMENT = '全部订单收入', orders.open_revenue AS SUM(orders.o_totalprice) FILTER (WHERE orders.o_status = 'O') COMMENT = '仅未完成(O)订单收入', orders.done_revenue AS SUM(orders.o_totalprice) FILTER (WHERE orders.o_status = 'F') COMMENT = '仅已完成(F)订单收入' );

按地区查询,三个口径一次取回:

SELECT * FROM semantic_view( doc_test.sv_conditional DIMENSIONS orders.region METRICS orders.total_revenue, orders.open_revenue, orders.done_revenue ) ORDER BY region;

+--------+---------------+--------------+--------------+ | region | total_revenue | open_revenue | done_revenue | +--------+---------------+--------------+--------------+ | East | 700.00 | 550.00 | 150.00 | | West | 700.00 | 200.00 | 500.00 | +--------+---------------+--------------+--------------+

每个

FILTER (WHERE ...)
FILTER (WHERE ...)
只对满足条件的行聚合,
open_revenue
open_revenue
done_revenue
done_revenue
之和等于
total_revenue
total_revenue

带算术与派生指标的语义视图

指标体可以直接写算术表达式(如

MAX(...) - MIN(...)
MAX(...) - MIN(...)
),也可以在同一逻辑表内引用其他已命名指标做运算(派生指标,如用总额除以人数得平均值)。前置数据:

CREATE TABLE doc_test.doc_arith_emp ( id INT, dept STRING, salary DECIMAL(12,2) ); INSERT INTO doc_test.doc_arith_emp VALUES (1, 'Engineering', 130000), (2, 'Engineering', 100000), (3, 'Marketing', 95000), (4, 'Marketing', 90000), (5, 'HR', 80000);

CREATE SEMANTIC VIEW doc_test.sv_arith TABLES ( emps AS doc_test.doc_arith_emp PRIMARY KEY (id) ) DIMENSIONS ( emps.department AS emps.dept ) METRICS ( emps.total_salary AS SUM(emps.salary), emps.headcount AS COUNT(emps.id), emps.salary_range AS MAX(emps.salary) - MIN(emps.salary), -- 算术表达式指标 emps.avg_salary AS emps.total_salary / emps.headcount -- 派生指标:引用同表其他指标 );

SELECT * FROM semantic_view( doc_test.sv_arith DIMENSIONS emps.department METRICS emps.total_salary, emps.headcount, emps.salary_range, emps.avg_salary ) ORDER BY department;

+-------------+--------------+-----------+--------------+----------------------------+ | department | total_salary | headcount | salary_range | avg_salary | +-------------+--------------+-----------+--------------+----------------------------+ | Engineering | 230000.00 | 2 | 30000.00 | 115000.000000000000000000 | | HR | 80000.00 | 1 | 0.00 | 80000.000000000000000000 | | Marketing | 185000.00 | 2 | 5000.00 | 92500.000000000000000000 | +-------------+--------------+-----------+--------------+----------------------------+

salary_range
salary_range
是同表两个聚合相减;
avg_salary
avg_salary
引用了本视图已定义的
total_salary
total_salary
headcount
headcount
相除。派生指标只能引用同一逻辑表内的其他指标。

带 PRIVATE 中间指标的语义视图

PRIVATE
PRIVATE
把中间计算量封装起来:它能被其他
PUBLIC
PUBLIC
指标组合引用,但不能被直接查询。适合只想暴露最终口径(如毛利率),隐藏中间量(总收入、总成本)的场景。前置数据:

CREATE TABLE doc_test.doc_priv_sales ( id INT, region STRING, revenue DECIMAL(12,2), cost DECIMAL(12,2) ); INSERT INTO doc_test.doc_priv_sales VALUES (1, 'East', 1000.00, 600.00), (2, 'East', 500.00, 300.00), (3, 'West', 800.00, 500.00);

CREATE SEMANTIC VIEW doc_test.sv_private TABLES ( sales AS doc_test.doc_priv_sales PRIMARY KEY (id) ) DIMENSIONS ( sales.region AS sales.region ) METRICS ( PRIVATE sales.total_rev AS SUM(sales.revenue), PRIVATE sales.total_cost AS SUM(sales.cost), sales.margin_pct AS (sales.total_rev - sales.total_cost) * 100.0 / sales.total_rev );

查询

PUBLIC
PUBLIC
margin_pct
margin_pct
正常返回(毛利率在每个分组按"总利润 / 总收入"重算):

SELECT * FROM semantic_view( doc_test.sv_private DIMENSIONS sales.region METRICS sales.margin_pct ) ORDER BY region;

+--------+-----------------+ | region | margin_pct | +--------+-----------------+ | East | 40.00000000000 | | West | 37.50000000000 | +--------+-----------------+

margin_pct
margin_pct
是 decimal 相除,返回高精度小数;需要两位百分比时外层套
ROUND(margin_pct, 2)
ROUND(margin_pct, 2)
。)

直接查询

PRIVATE
PRIVATE
指标会被拒绝:

SELECT * FROM semantic_view( doc_test.sv_private DIMENSIONS sales.region METRICS sales.total_rev );

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

带窗口函数指标的语义视图

指标体内可以使用窗口函数做占比、累计、排名。下例用

SUM(SUM(...)) OVER (PARTITION BY ...)
SUM(SUM(...)) OVER (PARTITION BY ...)
计算每个订单占其所在大区的收入比。关键约束:
PARTITION BY
PARTITION BY
必须写维度的限定别名
orders.region
orders.region
),不能写物理列名;查询时
region
region
维度也必须出现在
DIMENSIONS
DIMENSIONS
中。前置数据:

CREATE TABLE doc_test.doc_win_orders ( o_orderkey INT, o_region STRING, o_totalprice DECIMAL(12,2) ); INSERT INTO doc_test.doc_win_orders VALUES (101, 'East', 250.00), (102, 'East', 150.00), (103, 'East', 100.00), (104, 'West', 400.00), (105, 'West', 600.00);

CREATE SEMANTIC VIEW doc_test.sv_window TABLES ( orders AS doc_test.doc_win_orders PRIMARY KEY (o_orderkey) ) DIMENSIONS ( orders.region AS orders.o_region, orders.orderkey AS orders.o_orderkey ) METRICS ( orders.revenue AS SUM(orders.o_totalprice), orders.pct_of_region AS SUM(orders.o_totalprice) * 100.0 / SUM(SUM(orders.o_totalprice)) OVER (PARTITION BY orders.region) );

查询时把

region
region
PARTITION BY
PARTITION BY
用到的维度)和
orderkey
orderkey
一起放进
DIMENSIONS
DIMENSIONS

SELECT * FROM semantic_view( doc_test.sv_window DIMENSIONS orders.region, orders.orderkey METRICS orders.revenue, orders.pct_of_region ) ORDER BY region, orderkey;

+--------+----------+---------+------------------+ | region | orderkey | revenue | pct_of_region | +--------+----------+---------+------------------+ | East | 101 | 250.00 | 50.000000000000 | | East | 102 | 150.00 | 30.000000000000 | | East | 103 | 100.00 | 20.000000000000 | | West | 104 | 400.00 | 40.000000000000 | | West | 105 | 600.00 | 60.000000000000 | +--------+----------+---------+------------------+

每个大区内各订单占比合计 100%(East 50+30+20,West 40+60)。

pct_of_region
pct_of_region
同样是 decimal 相除的高精度结果,需要固定小数位时外层套
ROUND(...)
ROUND(...)

多层粒度阶梯语义视图

多张表通过外键串成一条粒度阶梯:父表粗、子表细,外键定义在子表上、指向父表主键。下例是经典的 region → customer → orders → lineitem 四层阶梯(地区最粗,明细行最细)。这套结构决定了指标能按哪些维度分组——同一个明细指标可以按任意更粗的层级上卷(roll-up),但父表指标不能直接聚合子表的列。前置数据:

CREATE TABLE doc_test.grain_region (r_regionkey INT, r_name STRING); CREATE TABLE doc_test.grain_customer (c_custkey INT, c_name STRING, c_regionkey INT); CREATE TABLE doc_test.grain_orders (o_orderkey INT, o_custkey INT, o_totalprice DECIMAL(12,2)); CREATE TABLE doc_test.grain_lineitem (l_orderkey INT, l_linenumber INT, l_price DECIMAL(12,2)); INSERT INTO doc_test.grain_region VALUES (1, 'East'), (2, 'West'); INSERT INTO doc_test.grain_customer VALUES (1, 'Alice', 1), (2, 'Bob', 1), (3, 'Carol', 2); INSERT INTO doc_test.grain_orders VALUES (101, 1, 300.00), (102, 1, 200.00), (103, 2, 500.00), (104, 3, 400.00); INSERT INTO doc_test.grain_lineitem VALUES (101, 1, 100.00), (101, 2, 200.00), (102, 1, 200.00), (103, 1, 150.00), (103, 2, 350.00), (104, 1, 400.00);

CREATE OR REPLACE SEMANTIC VIEW doc_test.sv_grain TABLES ( region AS doc_test.grain_region PRIMARY KEY (r_regionkey), customer AS doc_test.grain_customer PRIMARY KEY (c_custkey) FOREIGN KEY (c_regionkey) REFERENCES region, orders AS doc_test.grain_orders PRIMARY KEY (o_orderkey) FOREIGN KEY (o_custkey) REFERENCES customer, lineitem AS doc_test.grain_lineitem PRIMARY KEY (l_orderkey, l_linenumber) FOREIGN KEY (l_orderkey) REFERENCES orders ) DIMENSIONS ( region.region_name AS region.r_name, customer.customer_name AS customer.c_name, orders.orderkey AS orders.o_orderkey ) METRICS ( lineitem.line_revenue AS SUM(lineitem.l_price), orders.order_amount AS SUM(orders.o_totalprice) );

明细指标

line_revenue
line_revenue
(定义在最细的
lineitem
lineitem
表)可以按阶梯上任意更粗的层级分组,引擎自动沿外键 JOIN 上卷。按最粗的
region
region
分组:

SELECT * FROM semantic_view( doc_test.sv_grain DIMENSIONS region.region_name METRICS lineitem.line_revenue ) ORDER BY region_name;

+-------------+--------------+ | region_name | line_revenue | +-------------+--------------+ | East | 1000.00 | | West | 400.00 | +-------------+--------------+

按中间层

customer
customer
分组,同一指标自动重新聚合到客户粒度:

SELECT * FROM semantic_view( doc_test.sv_grain DIMENSIONS customer.customer_name METRICS lineitem.line_revenue ) ORDER BY customer_name;

+---------------+--------------+ | customer_name | line_revenue | +---------------+--------------+ | Alice | 500.00 | | Bob | 500.00 | | Carol | 400.00 | +---------------+--------------+

按最细的

orders
orders
分组:

SELECT * FROM semantic_view( doc_test.sv_grain DIMENSIONS orders.orderkey METRICS lineitem.line_revenue ) ORDER BY orderkey;

+----------+--------------+ | orderkey | line_revenue | +----------+--------------+ | 101 | 300.00 | | 102 | 200.00 | | 103 | 500.00 | | 104 | 400.00 | +----------+--------------+

同一个

line_revenue
line_revenue
在三个层级返回不同的聚合结果,粒度越粗数字越大,全局合计恒为 1400。这就是粒度阶梯的核心:指标定义一次,按任意父层级自动上卷。反过来,父表指标不能直接聚合子表列——
customer
customer
表的指标写
SUM(lineitem.l_price)
SUM(lineitem.l_price)
会报
cannot resolve column
cannot resolve column
,需要先用
FACTS
FACTS
把子表列透传上来。完整的粒度规则(上卷合法、下钻非法、无子行的父行 COUNT 返回 NULL 等)详见关系建模与聚合粒度

相关文档

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