diff --git a/docs/cn/guides/54-query/00-cte.md b/docs/cn/guides/54-query/00-cte.md index 2c5ca408e5..704e3cfdbf 100644 --- a/docs/cn/guides/54-query/00-cte.md +++ b/docs/cn/guides/54-query/00-cte.md @@ -1,15 +1,15 @@ --- -title: 公共表表达式 (CTE) +title: 通用表表达式(Common Table Expression,CTE) --- import FunctionDescription from '@site/src/components/FunctionDescription'; -Databend 支持使用 WITH 子句的公共表表达式 (CTE),允许您定义一个或多个命名的临时结果集供后续查询使用。"临时"意味着这些结果集不会永久存储在数据库模式中,它们仅作为临时视图供后续查询访问。 +Databend 支持带有 WITH 子句的通用表表达式(CTE),允许您定义一个或多个命名的临时结果集,供后续查询使用。"临时"表示结果集不会永久存储在数据库模式中,它们仅作为临时视图供后续查询访问。 -当执行带有 WITH 子句的查询时,WITH 子句中的 CTE 会首先被评估和执行,生成一个或多个临时结果集。然后查询会使用这些由 WITH 子句生成的临时结果集执行。 +执行带 WITH 子句的查询时,会先评估并执行 WITH 子句中的 CTE,生成一个或多个临时结果集。随后主查询将使用这些临时结果集进行执行。 -以下是一个简单示例帮助理解 CTE 在查询中的工作原理:WITH 子句定义了一个 CTE,生成包含魁北克省所有客户的结果集。主查询则从魁北克省的客户中筛选出居住在蒙特利尔地区的客户。 +以下简单示例演示 CTE 在查询中的工作原理:WITH 子句定义 CTE 并生成包含魁北克省所有客户的结果集,主查询则从该结果集中筛选居住在蒙特利尔地区的客户。 ```sql WITH customers_in_quebec @@ -23,7 +23,7 @@ WHERE city = 'Montréal' ORDER BY customername; ``` -CTE 可以简化使用子查询的复杂查询,使代码更易于阅读和维护。如果不使用 CTE,前面的示例将如下所示: +CTE 可简化使用子查询的复杂查询,提升代码可读性和可维护性。若不使用 CTE,前例将变为: ```sql SELECT customername @@ -37,9 +37,9 @@ ORDER BY customername; ## 内联还是物化? -在查询中使用 CTE 时,您可以通过 MATERIALIZED 关键字控制 CTE 是内联还是物化。内联意味着 CTE 的定义直接嵌入到主查询中,而物化 CTE 意味着计算其结果一次并存储在内存中,减少重复的 CTE 执行。 +查询中使用 CTE 时,可通过 MATERIALIZED 关键字控制 CTE 为内联或物化。内联表示 CTE 定义直接嵌入主查询,物化则会将 CTE 结果计算一次后存入内存,减少重复执行。 -假设我们有一个名为 *orders* 的表,存储客户订单信息,包括订单号、客户 ID 和订单日期。 +假设存在存储客户订单信息的 *orders* 表,包含订单号、客户 ID 和订单日期。 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -47,7 +47,7 @@ import TabItem from '@theme/TabItem'; -在此查询中,CTE *customer_orders* 将在查询执行时内联。Databend 会直接将 *customer_orders* 的定义嵌入到主查询中。 +此查询中 CTE *customer_orders* 将在执行时内联,Databend 会将其定义直接嵌入主查询。 ```sql WITH customer_orders AS ( @@ -64,7 +64,7 @@ WHERE co1.order_count > 2 -本例中我们使用 MATERIALIZED 关键字,意味着 CTE *customer_orders* 不会被内联。相反,CTE 的结果将在 CTE 定义执行时计算并存储在内存中。当执行主查询中的两个 CTE 实例时,Databend 会直接从内存中获取结果,避免冗余计算并可能提高性能。 +使用 MATERIALIZED 关键字时,CTE *customer_orders* 不会内联。其定义执行时会计算结果并存入内存,主查询中执行 CTE 实例时,Databend 直接从内存获取结果,避免冗余计算并可能提升性能。 ```sql WITH customer_orders AS MATERIALIZED ( @@ -78,12 +78,11 @@ JOIN customer_orders co2 ON co1.customer_id = co2.customer_id WHERE co1.order_count > 2 AND co2.order_count > 5; ``` -当 CTE 结果被多次使用时,这可以显著提高性能。但由于 CTE 不再内联,查询优化器可能难以将 CTE 的条件推入主查询或优化连接顺序,可能导致整体查询性能下降。 +此方式可显著提升多次使用 CTE 结果时的性能。但 CTE 不再内联后,查询优化器可能难以将 CTE 条件推入主查询或优化连接顺序,导致整体查询性能下降。 - ## 语法 ```sql @@ -94,16 +93,16 @@ WITH SELECT ... | UPDATE ... | DELETE FROM ... ``` -| 参数 | 描述 | -|------------------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| WITH | 启动 WITH 子句。 | -| cte_name1 ... cte_nameN | CTE 名称。当有多个 CTE 时,用逗号分隔。 | -| cte_column_list | CTE 中的列名。一个 CTE 可以引用同一 WITH 子句中之前定义的其他 CTE。 | -| MATERIALIZED | `Materialized` 是一个可选关键字,用于指示是否应将 CTE 物化。 | +| 参数 | 描述 | +|------------------|----------------------------------------------------------------------| +| WITH | 启动 WITH 子句 | +| cte_name1 ... N | CTE 名称,多个 CTE 需用逗号分隔 | +| cte_column_list | CTE 中的列名,可引用同一 WITH 子句中先前定义的 CTE | +| MATERIALIZED | 可选关键字,指示是否物化 CTE | ## 递归 CTE -递归 CTE 是一种通过自我引用来执行递归操作的临时结果集,允许处理层次结构或递归数据结构。 +递归 CTE 是通过自引用执行递归操作的临时结果集,用于处理层次化或递归数据结构。 ### 语法 @@ -115,31 +114,27 @@ WITH RECURSIVE AS ( SELECT ... ``` -| 参数 | 描述 | -|-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `cte_name` | CTE 名称。 | -| `initial_query` | 递归开始时执行一次的初始查询,通常返回一组行数据。 | -| `recursive_query` | 引用 CTE 自身并重复执行的查询,直到返回空结果集为止。必须包含对 CTE 名称的引用。该查询不得包含聚合函数 (如 MAX、MIN、SUM、AVG、COUNT)、窗口函数、GROUP BY 子句、ORDER BY 子句、LIMIT 子句或 DISTINCT。 | +| 参数 | 描述 | +|------------------|----------------------------------------------------------------------| +| `cte_name` | CTE 名称 | +| `initial_query` | 递归起始时执行一次的初始查询,通常返回行集合 | +| `recursive_query`| 自引用 CTE 的查询,重复执行直至返回空集,禁止包含聚合函数、窗口函数、GROUP BY、ORDER BY、LIMIT 或 DISTINCT | ### 工作原理 -递归 CTE 的执行顺序如下: - -1. **初始查询执行**:该查询形成基础结果集 R0,为递归提供起点。 - -2. **递归查询执行**:该查询使用前一次迭代的结果集 (从 R0 开始) 作为输入,生成新的结果集 Ri+1。 - -3. **迭代与合并**:递归执行持续进行迭代。每个新结果集 Ri 成为下一次迭代的输入,直到递归查询返回空结果集,表示终止条件已满足。 - -4. **最终结果集形成**:使用 `UNION ALL` 操作符将所有迭代结果集 (R0 到 Rn) 合并为单一结果集。`UNION ALL` 确保每个结果集的所有行都包含在最终合并结果中。 +递归 CTE 执行顺序如下: -5. **最终选择**:最后的 `SELECT ...` 语句从 CTE 中检索合并后的结果集,可对合并结果应用额外的过滤、排序等操作以生成最终输出。 +1. **初始查询执行**:形成基础结果集 R0,作为递归起点 +2. **递归查询执行**:使用前次迭代结果集(从 R0 开始)作为输入,生成新结果集 Ri+1 +3. **迭代与组合**:递归执行持续迭代,新结果集 Ri 成为下次迭代输入,直至返回空集(终止条件满足) +4. **最终结果集形成**:使用 `UNION ALL` 合并各次迭代结果集(R0 至 Rn) +5. **最终选择**:通过 `SELECT ...` 从 CTE 检索合并结果集,可进行额外过滤、排序等操作 ## 使用示例 ### 非递归 CTE -假设您管理 GTA 地区多家书店,使用表存储店铺 ID、区域和上月交易额。 +假设管理大多伦多地区多家书店,使用表存储店铺 ID、区域和上月交易量: ```sql CREATE TABLE sales @@ -158,10 +153,10 @@ INSERT INTO sales VALUES (6, 'Markham', 4350); INSERT INTO sales VALUES (7, 'North York', 2490); ``` -以下代码返回交易额低于平均值的店铺: +返回交易量低于平均值的店铺: ```sql --- 定义包含一个 CTE 的 WITH 子句 +-- 含单个 CTE 的 WITH 子句 WITH avg_all AS (SELECT Avg(amount) AVG_SALES FROM sales) @@ -185,10 +180,10 @@ WHERE sales.amount < avg_sales; └──────────────────────────────────────────────────────────────────────────┘ ``` -以下代码返回各区域平均交易额和总交易额: +返回各区域平均和总交易量: ```sql --- 定义包含两个 CTE 的 WITH 子句 +-- 含两个 CTE 的 WITH 子句 WITH avg_by_region AS (SELECT region, Avg (amount) avg_by_region_value @@ -220,7 +215,7 @@ WHERE avg_by_region.region = sum_by_region.region; └──────────────────────────────────────────────────────────────┘ ``` -以下代码将低于区域平均销售额的店铺交易额更新为 0: +将低于区域平均销售额的店铺交易量更新为 0: ```sql WITH region_avg_sales_cte AS ( @@ -237,7 +232,7 @@ WHERE amount < ( ); ``` -假设有另一个表 "store_details" 存储店铺额外信息(如开业日期和所有者): +假设存在存储店铺补充信息的 *store_details* 表: ```sql CREATE TABLE store_details ( @@ -254,7 +249,7 @@ INSERT INTO store_details VALUES (9, 'Mississauga Store', '2022-03-20', 'Emma Br INSERT INTO store_details VALUES (5, 'Scarborough Store', '2022-04-05', 'David Lee'); ``` -删除 "store_details" 表中没有销售记录的店铺: +删除 *store_details* 中无销售记录的店铺: ```sql WITH stores_with_sales AS ( @@ -267,7 +262,7 @@ WHERE storeid NOT IN (SELECT storeid FROM stores_with_sales); ### 递归 CTE -首先创建员工数据表,包含 ID、姓名和上级 ID: +创建存储员工 ID、姓名和经理 ID 的表: ```sql CREATE TABLE Employees ( @@ -277,7 +272,7 @@ CREATE TABLE Employees ( ); ``` -插入样本数据表示简单组织结构: +插入样本数据表示组织结构: ```sql INSERT INTO Employees (EmployeeID, EmployeeName, ManagerID) VALUES @@ -289,7 +284,7 @@ INSERT INTO Employees (EmployeeID, EmployeeName, ManagerID) VALUES (6, 'Frank', 3); -- Frank 向 Charlie 汇报 ``` -使用递归 CTE 查找特定管理者(如 Alice,EmployeeID = 1)下属的层级关系: +使用递归 CTE 查找特定经理(如 Alice)下属的员工层级: ```sql WITH RECURSIVE EmployeeHierarchy AS ( @@ -306,7 +301,7 @@ WITH RECURSIVE EmployeeHierarchy AS ( SELECT * FROM EmployeeHierarchy; ``` -输出显示 Alice 下属的所有员工层级: +输出 Alice 下属的所有员工: ```sql ┌─────────────────────────────────────────────────────────────────────────┐ diff --git a/docs/cn/guides/54-query/01-groupby/_category_.json b/docs/cn/guides/54-query/01-groupby/_category_.json index fa13515223..dea9d78ba3 100644 --- a/docs/cn/guides/54-query/01-groupby/_category_.json +++ b/docs/cn/guides/54-query/01-groupby/_category_.json @@ -1,3 +1 @@ -{ - "label": "GROUP BYs" -} \ No newline at end of file +{"label": "GROUP BY"} diff --git a/docs/cn/guides/54-query/01-groupby/group-by-cube.md b/docs/cn/guides/54-query/01-groupby/group-by-cube.md index e20b4310d4..739de612bd 100644 --- a/docs/cn/guides/54-query/01-groupby/group-by-cube.md +++ b/docs/cn/guides/54-query/01-groupby/group-by-cube.md @@ -2,9 +2,9 @@ title: GROUP BY CUBE --- -`GROUP BY CUBE` 是 [GROUP BY](index.md) 子句的扩展,类似于 [GROUP BY ROLLUP](group-by-rollup.md)。除了生成 `GROUP BY ROLLUP` 的所有行之外,`GROUP BY CUBE` 还会添加所有“交叉列表”行。小计行是进一步聚合的行,其值是通过计算用于生成分组行的相同聚合函数来导出的。 +`GROUP BY CUBE` 是 [GROUP BY](index.md) 子句的扩展,类似于 [GROUP BY ROLLUP](group-by-rollup.md)。除了生成 `GROUP BY ROLLUP` 的所有行之外,`GROUP BY CUBE` 还会添加所有"交叉表"行。小计行代表更高层级的聚合结果,其值通过计算与分组行相同的聚合函数得出。 -`CUBE` 分组等效于一系列分组集,本质上是一种更短的规范。CUBE 规范的 N 个元素对应于 `2^N GROUPING SETS`。 +`CUBE` 分组等价于一系列分组集(Grouping Sets),本质上是更简洁的表示形式。CUBE 规范的 N 个元素对应 `2^N` 个分组集。 ## 语法 @@ -21,15 +21,13 @@ GROUP BY CUBE ( groupCube [ , groupCube [ , ... ] ] ) groupCube ::= { | | } ``` -- ``: 查询块的 SELECT 列表中出现的列别名 - -- ``: SELECT 列表中表达式的位置 - -- ``: 当前作用域中表的任何表达式 +- ``:出现在查询块 SELECT 列表中的列别名 +- ``:表达式在 SELECT 列表中的位置 +- ``:当前范围内表上的任意表达式 ## 示例 -假设我们有一个 sales_data 表,其架构和示例数据如下: +假设存在以下结构和示例数据的 sales_data 表: ```sql CREATE TABLE sales_data ( @@ -47,7 +45,7 @@ INSERT INTO sales_data (region, product, sales_amount) VALUES ('West', 'WidgetB', 200); ``` -现在,让我们使用 `GROUP BY CUBE` 子句来获取每个地区和产品的总销售额,以及所有可能的聚合: +使用 `GROUP BY CUBE` 子句获取各地区和各产品的总销售额,以及所有可能的聚合结果: ```sql SELECT region, product, SUM(sales_amount) AS total_sales @@ -55,7 +53,7 @@ FROM sales_data GROUP BY CUBE (region, product); ``` -结果将是: +返回结果: ```sql +--------+---------+-------------+ | region | product | total_sales | diff --git a/docs/cn/guides/54-query/01-groupby/group-by-grouping-sets.md b/docs/cn/guides/54-query/01-groupby/group-by-grouping-sets.md index 17ae88bf8b..9aa40fb005 100644 --- a/docs/cn/guides/54-query/01-groupby/group-by-grouping-sets.md +++ b/docs/cn/guides/54-query/01-groupby/group-by-grouping-sets.md @@ -2,13 +2,12 @@ title: GROUP BY GROUPING SETS --- -`GROUP BY GROUPING SETS` 是 [GROUP BY](index.md) 子句的一个强大扩展,允许在单个语句中计算多个 group-by 子句。group set 是一组维度列。 +`GROUP BY GROUPING SETS` 是 [GROUP BY](index.md) 子句的强大扩展,支持在单个语句中计算多个分组操作。分组集是维度列的集合。 -`GROUP BY GROUPING SETS` 相当于同一结果集中两个或多个 GROUP BY 操作的 UNION: +`GROUP BY GROUPING SETS` 等效于在同一结果集中对多个 GROUP BY 操作执行 UNION: -- `GROUP BY GROUPING SETS((a))` 等价于单个分组集操作 `GROUP BY a`。 - -- `GROUP BY GROUPING SETS((a),(b))` 等价于 `GROUP BY a UNION ALL GROUP BY b`。 +- `GROUP BY GROUPING SETS((a))` 等效于单分组操作 `GROUP BY a` +- `GROUP BY GROUPING SETS((a),(b))` 等效于 `GROUP BY a UNION ALL GROUP BY b` ## 语法 @@ -25,17 +24,15 @@ GROUP BY GROUPING SETS ( groupSet [ , groupSet [ , ... ] ] ) groupSet ::= { | | } ``` -- ``: 查询块的 SELECT 列表中出现的列别名 - -- ``: SELECT 列表中表达式的位置 - -- ``: 当前作用域中表的任何表达式 +- ``:查询块 SELECT 列表中出现的列别名 +- ``:表达式在 SELECT 列表中的位置 +- ``:当前作用域内表上的任意表达式 ## 示例 示例数据设置: ```sql --- 创建一个示例销售表 +-- 创建示例销售表 CREATE TABLE sales ( id INT, sale_date DATE, @@ -44,7 +41,7 @@ CREATE TABLE sales ( quantity INT ); --- 将示例数据插入到销售表中 +-- 向销售表插入示例数据 INSERT INTO sales (id, sale_date, product_id, store_id, quantity) VALUES (1, '2021-01-01', 101, 1, 5), (2, '2021-01-01', 102, 1, 10), @@ -54,7 +51,7 @@ VALUES (1, '2021-01-01', 101, 1, 5), (6, '2021-01-02', 103, 2, 20); ``` -### GROUP BY GROUPING SETS 与列别名 +### 使用列别名的 GROUP BY GROUPING SETS ```sql SELECT product_id AS pid, @@ -64,7 +61,7 @@ FROM sales GROUP BY GROUPING SETS((pid), (sid)); ``` -这个查询等价于: +此查询等效于: ```sql SELECT product_id AS pid, @@ -93,7 +90,7 @@ GROUP BY sid; +------+------+----------------+ ``` -### GROUP BY GROUPING SETS 与位置 +### 使用位置的 GROUP BY GROUPING SETS ```sql SELECT product_id, @@ -103,7 +100,7 @@ FROM sales GROUP BY GROUPING SETS((1), (2)); ``` -这个查询等价于: +此查询等效于: ```sql SELECT product_id, diff --git a/docs/cn/guides/54-query/01-groupby/group-by-rollup.md b/docs/cn/guides/54-query/01-groupby/group-by-rollup.md index 32c0b8778f..92c1f9d807 100644 --- a/docs/cn/guides/54-query/01-groupby/group-by-rollup.md +++ b/docs/cn/guides/54-query/01-groupby/group-by-rollup.md @@ -2,7 +2,7 @@ title: GROUP BY ROLLUP --- -`GROUP BY ROLLUP` 是 [GROUP BY](index.md) 子句的扩展,用于生成小计行(除了分组行之外)。小计行是通过计算用于生成分组行的相同聚合函数来进一步聚合其值的行。 +`GROUP BY ROLLUP`(分组汇总)是 [GROUP BY](index.md) 子句的扩展,它除了生成分组行之外,还会生成小计行。小计行是进一步聚合的结果行,其值通过计算用于生成分组行的相同聚合函数得出。 ## 语法 @@ -15,21 +15,17 @@ GROUP BY ROLLUP ( groupRollup [ , groupRollup [ , ... ] ] ) ``` 其中: - ```sql groupRollup ::= { | | } ``` -- ``: 查询块的 SELECT 列表中出现的列别名 - -- ``: SELECT 列表中表达式的位置 - -- ``: 当前作用域中表的任何表达式 +- ``:出现在查询块 SELECT 列表中的列别名 +- ``:表达式在 SELECT 列表中的位置 +- ``:当前作用域内表上的任何表达式 ## 示例 -让我们创建一个名为 sales_data 的示例表并插入一些数据: - +创建示例表 `sales_data` 并插入数据: ```sql CREATE TABLE sales_data ( region VARCHAR(255), @@ -46,16 +42,14 @@ INSERT INTO sales_data (region, product, sales_amount) VALUES ('West', 'WidgetB', 200); ``` -现在,让我们使用 GROUP BY ROLLUP 子句来获取每个地区和产品的总销售额,以及每个地区的小计: - +使用 `GROUP BY ROLLUP` 子句获取各地区-产品的总销售额及各地区小计: ```sql SELECT region, product, SUM(sales_amount) AS total_sales FROM sales_data GROUP BY ROLLUP (region, product); ``` -结果将是: - +执行结果: ```sql +--------+---------+-------------+ | region | product | total_sales | @@ -73,4 +67,4 @@ GROUP BY ROLLUP (region, product); +--------+---------+-------------+ ``` -在此示例中,GROUP BY ROLLUP 子句计算每个地区 - 产品组合、每个地区和总计的销售总额。 +此示例中,`GROUP BY ROLLUP` 子句计算了每个地区-产品组合的总销售额、各地区的总销售额以及总计。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-groupby/index.md b/docs/cn/guides/54-query/01-groupby/index.md index 875e0a79d3..cdc97fc910 100644 --- a/docs/cn/guides/54-query/01-groupby/index.md +++ b/docs/cn/guides/54-query/01-groupby/index.md @@ -1,14 +1,13 @@ --- title: GROUP BY --- - import FunctionDescription from '@site/src/components/FunctionDescription'; - + -GROUP BY 语句允许你基于相同的 group-by-item 表达式对行进行分组,然后将聚合函数应用于每个生成组。group-by-item 表达式可以包括列名或别名、对 SELECT 列表中位置的数字引用、通用表达式或 SELECT 列表中的所有非聚合项。 +GROUP BY 子句用于根据相同的分组表达式对行进行分组,并对每个结果组应用聚合函数。分组表达式可包含列名或别名、SELECT 列表中位置的数值引用、通用表达式,或 SELECT 列表中的所有非聚合项。 -Databend 中的 GROUP BY 语句具有以下扩展,可实现更全面的数据分组和多功能的数据分析: +Databend 的 GROUP BY 子句提供以下扩展功能,支持更全面的数据分组和灵活分析: - [GROUP BY CUBE](group-by-cube.md) - [GROUP BY GROUPING SETS](group-by-grouping-sets.md) @@ -24,20 +23,20 @@ GROUP BY [ ALL | groupItem [ , groupItem [ , ... ] ] ] [ ... ] ``` -其中: +参数说明: -- **ALL**: 当使用关键字 "ALL" 时,Databend 会根据 SELECT 列表中的所有非聚合项对数据进行分组。 -- **groupItem**: groupItem 可以是以下之一: - - 在 SELECT 列表中定义的列名或别名。 - - 对 SELECT 列表中列位置的数字引用。 - - 涉及当前查询上下文中使用的表的列的任何表达式。 +- **ALL**:使用该关键字时,Databend 会按 SELECT 列表中的所有非聚合项分组 +- **groupItem**:分组项可为以下任意类型: + - SELECT 列表中定义的列名或别名 + - SELECT 列表中列位置的数值引用 + - 涉及当前查询表列的任意表达式 ## 示例 -本节中的 GROUP BY 示例基于以下数据设置: +本节示例基于以下数据准备: ```sql --- 创建一个名为 "employees" 的示例表 +-- 创建示例表 "employees" CREATE TABLE employees ( id INT, first_name VARCHAR(50), @@ -47,7 +46,7 @@ CREATE TABLE employees ( hire_date DATE ); --- 将示例数据插入到 "employees" 表中 +-- 向 "employees" 表插入数据 INSERT INTO employees (id, first_name, last_name, department_id, job_id, hire_date) VALUES (1, 'John', 'Doe', 1, 101, '2021-01-15'), (2, 'Jane', 'Smith', 1, 101, '2021-02-20'), @@ -57,10 +56,9 @@ VALUES (1, 'John', 'Doe', 1, 101, '2021-01-15'), (6, 'Eve', 'Davis', 2, 202, '2021-04-15'); ``` -### 按一列分组 - -此查询按 `department_id` 对员工进行分组,并计算每个部门中的员工人数: +### 单列分组 +按 `department_id` 分组统计各部门员工数: ```sql SELECT department_id, COUNT(*) AS num_employees FROM employees @@ -68,7 +66,6 @@ GROUP BY department_id; ``` 输出: - ```sql +---------------+---------------+ | department_id | num_employees | @@ -78,10 +75,9 @@ GROUP BY department_id; +---------------+---------------+ ``` -### 按多列分组 - -此查询按 `department_id` 和 `job_id` 对员工进行分组,然后计算每个组中的员工人数: +### 多列分组 +按 `department_id` 和 `job_id` 分组统计各组合员工数: ```sql SELECT department_id, job_id, COUNT(*) AS num_employees FROM employees @@ -89,7 +85,6 @@ GROUP BY department_id, job_id; ``` 输出: - ```sql +---------------+--------+---------------+ | department_id | job_id | num_employees | @@ -101,10 +96,9 @@ GROUP BY department_id, job_id; +---------------+--------+---------------+ ``` -### Group By ALL - -此查询使用 GROUP BY ALL 子句对员工进行分组,该子句对 SELECT 列表中的所有非聚合列进行分组。请注意,在这种情况下,结果将与按 `department_id` 和 `job_id` 分组相同,因为这些是 SELECT 列表中存在的唯一非聚合项。 +### ALL 分组 +使用 GROUP BY ALL 按 SELECT 列表所有非聚合列分组: ```sql SELECT department_id, job_id, COUNT(*) AS num_employees FROM employees @@ -112,7 +106,6 @@ GROUP BY ALL; ``` 输出: - ```sql +---------------+--------+---------------+ | department_id | job_id | num_employees | @@ -124,10 +117,9 @@ GROUP BY ALL; +---------------+--------+---------------+ ``` -### 按位置分组 - -此查询等效于上面的“按一列分组”示例。位置 1 指的是 SELECT 列表中的第一个项目,即 `department_id`: +### 位置分组 +按 SELECT 列表第 1 位(`department_id`)分组: ```sql SELECT department_id, COUNT(*) AS num_employees FROM employees @@ -135,7 +127,6 @@ GROUP BY 1; ``` 输出: - ```sql +---------------+---------------+ | department_id | num_employees | @@ -145,10 +136,9 @@ GROUP BY 1; +---------------+---------------+ ``` -### 按表达式分组 - -此查询按员工的雇用年份对员工进行分组,并计算每年雇用的员工人数: +### 表达式分组 +按入职年份分组统计每年招聘人数: ```sql SELECT EXTRACT(YEAR FROM hire_date) AS hire_year, COUNT(*) AS num_hires FROM employees @@ -156,11 +146,10 @@ GROUP BY EXTRACT(YEAR FROM hire_date); ``` 输出: - ```sql +-----------+-----------+ | hire_year | num_hires | +-----------+-----------+ | 2021 | 6 | +-----------+-----------+ -``` +``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-join.md b/docs/cn/guides/54-query/02-join.md index b2836f6854..cef05d5ac3 100644 --- a/docs/cn/guides/54-query/02-join.md +++ b/docs/cn/guides/54-query/02-join.md @@ -4,7 +4,7 @@ title: 连接(JOIN) ## 支持的连接类型 -*连接(join)* 将两个或多个表的列组合成单个结果集。Databend 支持以下连接类型: +*连接(Join)* 将两个或多个表的列组合到单个结果集中。Databend 支持以下 *连接(Join)* 类型: * [内连接(Inner Join)](#inner-join) * [自然连接(Natural Join)](#natural-join) @@ -17,7 +17,7 @@ title: 连接(JOIN) ## 示例表 -除非明确指定,本页面的连接示例均基于以下表: +除非明确指定,本页面的连接示例基于以下表创建: 表 "vip_info":存储 VIP 客户信息。 @@ -47,7 +47,7 @@ title: 连接(JOIN) ## 内连接(Inner Join) -*内连接* 返回结果集中满足连接条件的行。 +*内连接(Inner Join)* 返回结果集中满足连接条件的行。 ### 语法 @@ -64,7 +64,7 @@ FROM table_a 关键字 INNER 可选。 ::: -当通过等值运算符连接公共列时,可使用 USING 简化语法: +当基于公共列使用等值连接时,可用 USING 简化语法: ```sql SELECT select_list @@ -88,7 +88,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -99,7 +99,7 @@ FROM vip_info ## 自然连接(Natural Join) -*自然连接* 基于两表所有同名列自动连接。 +*自然连接(Natural Join)* 基于两个表所有同名列进行连接。 ### 语法 @@ -122,7 +122,7 @@ FROM vip_info NATURAL JOIN purchase_records; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -133,7 +133,7 @@ FROM vip_info ## 交叉连接(Cross Join) -*交叉连接* 返回左表每行与右表每行的组合结果。 +*交叉连接(Cross Join)* 返回第一个表每行与第二个表每行的组合结果。 ### 语法 @@ -153,7 +153,7 @@ FROM vip_info CROSS JOIN gift; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -174,7 +174,7 @@ FROM vip_info ## 左连接(Left Join) -*左连接* 返回左表所有记录及右表匹配记录,无匹配时右表字段为 NULL。 +*左连接(Left Join)* 返回左表所有记录及右表匹配记录。若无匹配,右表字段返回 NULL。 ### 语法 @@ -201,7 +201,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -213,7 +213,7 @@ FROM vip_info ## 右连接(Right Join) -*右连接* 返回右表所有记录及左表匹配记录,无匹配时左表字段为 NULL。 +*右连接(Right Join)* 返回右表所有记录及左表匹配记录。若无匹配,左表字段返回 NULL。 ### 语法 @@ -230,7 +230,7 @@ FROM table_a ### 示例 -返回所有购买记录对应的 VIP 信息(无匹配时显示 NULL): +返回所有购买记录对应的 VIP 信息(无 VIP 信息时显示 NULL): ```sql SELECT vip_info.client_id, @@ -240,7 +240,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -253,7 +253,7 @@ NULL|NULL ## 全外连接(Full Outer Join) -*全外连接* 返回两表所有记录,匹配行合并,无匹配处填充 NULL。 +*全外连接(Full Outer Join)* 返回两表所有行,匹配行合并显示,无匹配行处填充 NULL。 ### 语法 @@ -270,7 +270,7 @@ FROM table_a ### 示例 -返回两表所有匹配及未匹配行: +返回两表所有匹配及未匹配的行: ```sql SELECT vip_info.region, @@ -280,7 +280,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -294,8 +294,7 @@ NULL|Soda ## 左/右半连接(Left / Right Semi Join) -*左半连接* 返回左表中与右表匹配的行。 -*右半连接* 返回右表中与左表匹配的行。 +*左半连接(Left Semi Join)* 返回左表中与右表匹配的行。*右半连接(Right Semi Join)* 返回右表中与左表匹配的行。 ### 语法 @@ -324,7 +323,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -342,7 +341,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -353,8 +352,7 @@ FROM vip_info ## 左/右反连接(Left / Right Anti Join) -*左反连接* 返回左表中与右表无匹配的行。 -*右反连接* 返回右表中与左表无匹配的行。 +*左反连接(Left Anti Join)* 返回左表中与右表不匹配的行。*右反连接(Right Anti Join)* 返回右表中与左表不匹配的行。 ### 语法 @@ -383,7 +381,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: @@ -400,7 +398,7 @@ FROM vip_info ON vip_info.client_id = purchase_records.client_id; ``` -表定义详见[示例表](#example-tables)。 +表定义详见 [示例表](#example-tables)。 输出: diff --git a/docs/cn/guides/54-query/02-sequences.md b/docs/cn/guides/54-query/02-sequences.md index b1e18079f9..3339bc5207 100644 --- a/docs/cn/guides/54-query/02-sequences.md +++ b/docs/cn/guides/54-query/02-sequences.md @@ -1,6 +1,6 @@ --- -title: '使用 Sequence' -sidebar_label: 'Sequence' +title: '使用序列' +sidebar_label: '序列' --- import ComponentContent from '../../sql-reference/10-sql-commands/00-ddl/04-sequence/create-sequence.md'; diff --git a/docs/cn/guides/54-query/03-udf.md b/docs/cn/guides/54-query/03-udf.md index 11b62a3433..8ef2167c08 100644 --- a/docs/cn/guides/54-query/03-udf.md +++ b/docs/cn/guides/54-query/03-udf.md @@ -1,5 +1,5 @@ --- -title: 用户自定义函数 +title: 用户定义函数(User-Defined Function) --- import IndexOverviewList from '@site/src/components/IndexOverviewList'; @@ -8,18 +8,18 @@ import EEFeature from '@site/src/components/EEFeature'; -用户自定义函数(UDF)通过支持匿名 lambda 表达式和预定义的处理程序(Python、JavaScript 和 WebAssembly)来定义 UDF,从而提供增强的灵活性。这些功能允许用户创建根据其特定数据处理需求量身定制的自定义操作。Databend UDF 分为以下类型: +用户定义函数(User-Defined Functions,UDFs)通过支持匿名 lambda 表达式和预定义处理程序(Python、JavaScript 和 WebAssembly)来定义 UDF,提供更强的灵活性。这些功能让用户能够创建满足特定数据处理需求的自定义操作。Databend UDF 分为以下类型: - [Lambda UDFs](#lambda-udfs) -- [Embedded UDFs](#embedded-udfs) +- [嵌入式 UDFs(Embedded UDFs)](#embedded-udfs) ## Lambda UDFs -lambda UDF 允许用户直接在其查询中使用匿名函数(lambda 表达式)定义自定义操作。这些 lambda 表达式通常简洁明了,可用于执行特定的数据转换或计算,而这些转换或计算可能无法仅使用内置函数来实现。 +Lambda UDF 允许用户在查询中直接使用匿名函数(lambda 表达式)定义自定义操作。这些 lambda 表达式通常很简洁,可用于执行特定的数据转换或计算,这些操作可能无法仅通过内置函数实现。 ### 使用示例 -此示例创建 UDF,以使用 SQL 查询从表中的 JSON 数据中提取特定值。 +本示例创建 UDF,通过 SQL 查询从表中的 JSON 数据提取特定值。 ```sql CREATE OR REPLACE TABLE sale_items ( @@ -28,13 +28,13 @@ CREATE OR REPLACE TABLE sale_items ( ); INSERT INTO sale_items VALUES - (1, PARSE_JSON('{"name": "T-Shirt", "price": 20.00, "discount_pct": 10}')), -- 10% discount - (2, PARSE_JSON('{"name": "Jeans", "price": 50.00, "discount_pct": 25}')), -- 25% discount - (3, PARSE_JSON('{"name": "Jacket", "price": 100.00, "discount_pct": 0}')), -- No discount - (4, PARSE_JSON('{"name": "Socks", "price": 5.00, "discount_pct": 50}')); -- 50% discount + (1, PARSE_JSON('{"name": "T-Shirt", "price": 20.00, "discount_pct": 10}')), -- 10% 折扣 + (2, PARSE_JSON('{"name": "Jeans", "price": 50.00, "discount_pct": 25}')), -- 25% 折扣 + (3, PARSE_JSON('{"name": "Jacket", "price": 100.00, "discount_pct": 0}')), -- 无折扣 + (4, PARSE_JSON('{"name": "Socks", "price": 5.00, "discount_pct": 50}')); -- 50% 折扣 --- Define a Lambda UDF to calculate the final price after discount --- WITH EXPLICIT CASTING +-- 定义 Lambda UDF 计算折扣后最终价格 +-- 使用显式类型转换 CREATE OR REPLACE FUNCTION calculate_final_price AS (item_info) -> (item_info['price']::FLOAT) * (1 - (item_info['discount_pct']::FLOAT) / 100.0); @@ -45,7 +45,7 @@ SHOW USER FUNCTIONS; --| calculate_final_price | 0 | | {"parameters":["item_info"]} | SQL | YYYY-MM-DD HH:MM:SS.ffffff | --+-----------------------+----------------+-------------+---------------------------------+----------+----------------------------+ --- Use the Lambda UDF to get item names and their final prices +-- 使用 Lambda UDF 获取商品名称和最终价格 SELECT item_id, details['name']::STRING AS item_name, @@ -54,7 +54,7 @@ SELECT FROM sale_items ORDER BY item_id; --- Expected output for the SELECT query (final_price should now have values): +-- SELECT 查询预期输出(final_price 应有值): --+---------+-----------+----------------+-------------+ --| item_id | item_name | original_price | final_price | --+---------+-----------+----------------+-------------+ @@ -65,27 +65,27 @@ ORDER BY item_id; --+---------+-----------+----------------+-------------+ ``` -## Embedded UDFs +## 嵌入式 UDFs(Embedded UDFs) -通过嵌入式 UDF,您可以将使用以下编程语言编写的代码嵌入到 SQL 中: +嵌入式 UDF 允许在 SQL 中嵌入以下编程语言编写的代码: - [Python](#python) - [JavaScript](#javascript) - [WebAssembly](#webassembly) -使用嵌入式 UDF,您可以创建标量函数和聚合函数。标量函数对单行输入进行操作并返回单个值,而聚合函数处理多行输入并返回单个聚合结果,例如总和或平均值。 +通过嵌入式 UDF,可创建标量函数和聚合函数。标量函数对单行输入进行操作并返回单个值,聚合函数处理多行输入数据并返回单个聚合结果(如求和或平均值)。 :::note -- 尚不支持使用 WebAssembly 创建聚合 UDF。 -- 如果您的程序内容很大,您可以对其进行压缩,然后将其传递到 Stage。有关 WebAssembly,请参见[使用示例](#usage-examples-2)。 +- 暂不支持使用 WebAssembly 创建聚合 UDF +- 若程序内容较大,可压缩后传递到 stage,详见 WebAssembly 的[使用示例](#usage-examples-2) ::: -### Python (需要 Databend Enterprise) +### Python(需 Databend 企业版) -通过 Python UDF,您可以经由 Databend 的内置处理程序从 SQL 查询调用 Python 代码,从而可以在 SQL 查询中无缝集成 Python 逻辑。 +Python UDF 允许通过 Databend 内置处理器在 SQL 查询中调用 Python 代码,实现 Python 逻辑与 SQL 查询的无缝集成。 :::note -Python UDF 必须仅使用 Python 的标准库;不允许第三方导入。 +Python UDF 仅能使用 Python 标准库,禁止导入第三方库 ::: #### 数据类型映射 @@ -114,13 +114,13 @@ Python UDF 必须仅使用 Python 的标准库;不允许第三方导入。 #### 使用示例 ```sql --- Create a table with user interaction logs +-- 创建用户交互日志表 CREATE TABLE user_interaction_logs ( log_id INT, - log_data VARIANT -- JSON interaction log + log_data VARIANT -- JSON 交互日志 ); --- Insert sample interaction log data +-- 插入示例交互日志数据 INSERT INTO user_interaction_logs VALUES (1, PARSE_JSON('{"user_id": "u123", "timestamp": "2023-01-15T10:00:00Z", "action": "view_product", "details": {"product_id": "p789", "category": "electronics", "price": 99.99}}')), (2, PARSE_JSON('{"user_id": "u456", "timestamp": "2023-01-15T10:05:10Z", "action": "add_to_cart", "details": {"product_id": "p789", "quantity": 1, "category": "electronics"}}')), @@ -129,7 +129,7 @@ INSERT INTO user_interaction_logs VALUES (5, PARSE_JSON('{"user_id": "u123", "timestamp": "2023-01-15T10:10:00Z", "action": "view_page", "details": {"page_name": "homepage"}}')), (6, PARSE_JSON('{"user_id": "u456", "timestamp": "2023-01-15T10:12:00Z", "action": "purchase", "details": {"order_id": "o556", "total_amount": 25.00, "item_count": 1}}')); --- Create a Python UDF to extract features from interaction logs +-- 创建 Python UDF 从交互日志提取特征 CREATE OR REPLACE FUNCTION extract_interaction_features_py(VARIANT) RETURNS VARCHAR LANGUAGE python HANDLER = 'extract_features' @@ -182,7 +182,7 @@ def extract_features(log): return json.dumps(result_dict) $$; --- Use the Python UDF to extract features +-- 使用 Python UDF 提取特征 SELECT log_id, log_data['user_id']::STRING AS user_id, @@ -197,12 +197,11 @@ ORDER BY ### JavaScript -通过 JavaScript UDF,您可以经由 Databend 的内置处理程序从 SQL 查询调用 JavaScript 代码,从而可以在 SQL 查询中无缝集成 JavaScript 逻辑。 +JavaScript UDF 允许通过 Databend 内置处理器在 SQL 查询中调用 JavaScript 代码,实现 JavaScript 逻辑与 SQL 查询的无缝集成。 #### 数据类型映射 - -| Databend Type | JS Type | +| Databend 类型 | JS 类型 | | ----------------- | ---------- | | NULL | null | | BOOLEAN | Boolean | @@ -224,13 +223,13 @@ ORDER BY #### 使用示例 ```sql --- Create a table with user interaction logs +-- 创建用户交互日志表 CREATE TABLE user_interaction_logs ( log_id INT, - log_data VARIANT -- JSON interaction log + log_data VARIANT -- JSON 交互日志 ); --- Insert sample interaction log data +-- 插入示例交互日志数据 INSERT INTO user_interaction_logs VALUES (1, PARSE_JSON('{"user_id": "u123", "timestamp": "2023-01-15T10:00:00Z", "action": "view_product", "details": {"product_id": "p789", "category": "electronics", "price": 99.99}}')), (2, PARSE_JSON('{"user_id": "u456", "timestamp": "2023-01-15T10:05:10Z", "action": "add_to_cart", "details": {"product_id": "p789", "quantity": 1, "category": "electronics"}}')), @@ -240,8 +239,7 @@ INSERT INTO user_interaction_logs VALUES (6, PARSE_JSON('{"user_id": "u456", "timestamp": "2023-01-15T10:12:00Z", "action": "purchase", "details": {"order_id": "o556", "total_amount": 25.00, "item_count": 1}}')); -```md --- Create a JavaScript UDF to extract features from interaction logs +-- 创建 JavaScript UDF 从交互日志提取特征 CREATE FUNCTION extract_interaction_features_js(VARIANT) RETURNS VARIANT LANGUAGE javascript HANDLER = 'extractFeatures' @@ -283,7 +281,7 @@ export function extractFeatures(log) { return { is_search_action: isSearchAction, - has_product_interaction: has_product_interaction, + has_product_interaction: hasProductInteraction, product_category_if_any: productCategoryIfAny, search_query_length: searchQueryLength, purchase_value_bucket: purchaseValueBucket @@ -294,16 +292,19 @@ $$; ### WebAssembly -WebAssembly UDF 允许用户使用编译为 WebAssembly 的语言定义自定义逻辑或操作。然后,可以在 SQL 查询中直接调用这些 UDF,以执行特定的计算或数据转换。 +WebAssembly UDF 允许使用可编译为 WebAssembly 的语言定义自定义逻辑或操作,这些 UDF 可直接在 SQL 查询中调用以执行特定计算或数据转换。 -#### Usage Examples +#### 使用示例 -在此示例中,创建 "wasm_gcd" 函数来计算两个整数的最大公约数 (GCD)。该函数使用 WebAssembly 定义,其实现在 'test10_udf_wasm_gcd.wasm.zst' 二进制文件中。 +本示例创建 "wasm_gcd" 函数计算两个整数的最大公约数(GCD)。该函数使用 WebAssembly 定义,其实现位于 'test10_udf_wasm_gcd.wasm.zst' 二进制文件中。 -在执行之前,函数实现会经过一系列步骤。首先,它被编译成一个二进制文件,然后被压缩成 'test10_udf_wasm_gcd.wasm.zst'。最后,压缩后的文件会提前上传到 Stage。 +执行前需经过以下步骤: +1. 将函数实现编译为二进制文件 +2. 压缩为 'test10_udf_wasm_gcd.wasm.zst' +3. 提前将压缩文件上传至 stage :::note -该函数可以使用 Rust 实现,如 https://github.com/arrow-udf/arrow-udf/blob/main/arrow-udf-example/src/lib.rs 上的示例所示。 +该函数可用 Rust 实现,示例见:https://github.com/arrow-udf/arrow-udf/blob/main/arrow-udf-example/src/lib.rs ::: ```sql @@ -319,6 +320,6 @@ WHERE ORDER BY 1; ``` -## Managing UDFs +## 管理 UDF -Databend 提供了各种命令来管理 UDF。有关详细信息,请参见 [User-Defined Function](/sql/sql-commands/ddl/udf/)。{/*examples*/} +Databend 提供多种命令管理 UDF,详见[用户定义函数(User-Defined Function)](/sql/sql-commands/ddl/udf/)。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/04-external-function.md b/docs/cn/guides/54-query/04-external-function.md index 93400e1d52..789f3a0c25 100644 --- a/docs/cn/guides/54-query/04-external-function.md +++ b/docs/cn/guides/54-query/04-external-function.md @@ -1,49 +1,50 @@ +```markdown --- title: "Databend Cloud 中的外部函数" sidebar_label: "外部函数" --- -Databend 中的外部函数允许您使用 Python 等编程语言编写的外部服务器来定义用于处理数据的自定义操作。这些函数使您能够通过集成自定义逻辑、利用外部库和处理复杂的处理任务来扩展 Databend 的功能。外部函数的主要功能包括: +Databend 的外部函数允许您使用 Python 等编程语言编写的外部服务器定义数据处理的自定义操作。这些函数通过集成自定义逻辑、利用外部库和处理复杂任务来扩展 Databend 的能力。外部函数的主要特性包括: -- **可扩展性**:非常适合复杂且资源密集型的数据操作。 -- **外部库**:通过外部库和依赖项利用其他功能。 -- **高级逻辑**:为复杂的场景实施复杂的数据处理逻辑。 +- **可扩展性**:适用于复杂且资源密集型的数据操作 +- **外部库支持**:通过外部库和依赖项扩展功能 +- **高级逻辑**:实现复杂场景下的数据处理逻辑 ## 支持的编程语言 -下表列出了支持的语言以及在 Databend 中创建外部函数所需的库: +下表列出了在 Databend 中创建外部函数支持的语言及所需库: -| 语言 | 必需的库 | -| ---- | ----------------------------------------- | -| Python | [databend-udf](https://pypi.org/project/databend-udf) | +| 语言 | 所需库 | +| ------ | -------------------------------------------------------- | +| Python | [databend-udf](https://pypi.org/project/databend-udf) | ## 管理外部函数 -您可以使用 SQL 命令(例如 `CREATE FUNCTION`、`DROP FUNCTION` 和 `SHOW FUNCTIONS`)来管理外部函数。有关更多详细信息,请参见 [外部函数](/sql/sql-commands/ddl/external-function/)。 +您可以使用 `CREATE FUNCTION`、`DROP FUNCTION` 和 `SHOW FUNCTIONS` 等 SQL 命令管理外部函数。详见[外部函数文档](/sql/sql-commands/ddl/external-function/)。 ## 在 Databend Cloud 中配置外部函数 -要在 Databend Cloud 中使用外部函数,您需要**将外部函数服务器的地址加入白名单**。外部函数服务器必须可以通过 HTTPS 上的域名访问。请联系 Databend Cloud 支持以添加您允许的 UDF 服务器地址: +在 Databend Cloud 中使用外部函数需**将外部函数服务器地址加入允许列表**。外部服务器必须通过 HTTPS 域名访问。请联系 Databend Cloud 技术支持添加 UDF 服务器地址: -1. 在 Databend Cloud 控制台中,导航至 **支持** > **创建新工单**。 -2. 提供您希望加入白名单的外部服务器地址(带有 HTTPS 域名)。 -3. 提交工单并等待支持团队的确认。 +1. 在控制台进入 **支持** > **新建工单** +2. 提供需加入允许列表的 HTTPS 域名地址 +3. 提交工单并等待支持团队确认 -## 使用示例:在 Python 中创建外部函数 +## 使用示例:创建 Python 外部函数 本节演示如何使用 Python 创建外部函数。 -### 1. 安装所需的库 +### 1. 安装所需库 -使用 `pip` 安装 [databend-udf](https://pypi.org/project/databend-udf) 库: +通过 `pip` 安装依赖库: ```bash pip install databend-udf ``` -### 2. 定义您的函数 +### 2. 定义函数 -创建一个 Python 文件(例如,`external_function.py`)并定义您的外部函数。以下示例在 Python 中定义了一个外部服务器,该服务器公开了一个自定义函数 `gcd`,用于计算两个整数的最大公约数: +创建 Python 文件(如 `external_function.py`)并定义函数。以下示例实现计算两整数最大公约数的 `gcd` 函数: ```python from databend_udf import udf, UDFServer @@ -59,57 +60,54 @@ def gcd(x: int, y: int) -> int: return x if __name__ == '__main__': - # Create an external server listening at '0.0.0.0:8815' server = UDFServer("0.0.0.0:8815") - # Add the defined function server.add_function(gcd) - # Start the external server server.serve() ``` **`@udf` 装饰器参数说明:** -| 参数 | 描述 | -| --------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| `input_types` | 指定输入数据类型的字符串列表(例如,`["INT", "VARCHAR"]`)。 | -| `result_type` | 指定返回值类型的字符串(例如,`"INT"`)。 | -| `name` | (可选)函数的自定义名称。如果未提供,则使用原始函数名称。 | -| `io_threads` | 每个数据块用于 I/O 绑定函数的 I/O 线程数。 | -| `skip_null` | 如果设置为 `True`,则不会将 NULL 值传递给函数,并且相应的返回值设置为 NULL。默认为 `False`。 | - -**Databend 和 Python 之间的数据类型映射:** - -| Databend 类型 | Python 类型 | -| ------------------ | ------------------ | -| BOOLEAN | `bool` | -| TINYINT (UNSIGNED) | `int` | -| SMALLINT (UNSIGNED)| `int` | -| INT (UNSIGNED) | `int` | -| BIGINT (UNSIGNED) | `int` | -| FLOAT | `float` | -| DOUBLE | `float` | -| DECIMAL | `decimal.Decimal` | -| DATE | `datetime.date` | -| TIMESTAMP | `datetime.datetime`| -| VARCHAR | `str` | -| VARIANT | `any` | -| MAP(K,V) | `dict` | -| ARRAY(T) | `list[T]` | -| TUPLE(T,...) | `tuple(T,...)` | - -### 3. 运行外部服务器 - -运行 Python 文件以启动外部服务器: +| 参数 | 描述 | +| ------------- | -------------------------------------------------------------------- | +| `input_types` | 输入数据类型列表(如 `["INT", "VARCHAR"]`) | +| `result_type` | 返回值类型(如 `"INT"`) | +| `name` | (可选)函数自定义名称,默认使用原函数名 | +| `io_threads` | I/O 密集型函数中每个数据块使用的 I/O 线程数 | +| `skip_null` | 设为 `True` 时跳过 NULL 值,返回值自动设为 NULL(默认 `False`) | + +**Databend 与 Python 数据类型映射:** + +| Databend 类型 | Python 类型 | +| ------------------- | ------------------- | +| BOOLEAN | `bool` | +| TINYINT (UNSIGNED) | `int` | +| SMALLINT (UNSIGNED) | `int` | +| INT (UNSIGNED) | `int` | +| BIGINT (UNSIGNED) | `int` | +| FLOAT | `float` | +| DOUBLE | `float` | +| DECIMAL | `decimal.Decimal` | +| DATE | `datetime.date` | +| TIMESTAMP | `datetime.datetime` | +| VARCHAR | `str` | +| VARIANT | `any` | +| MAP(K,V) | `dict` | +| ARRAY(T) | `list[T]` | +| TUPLE(T,...) | `tuple(T,...)` | + +### 3. 启动外部服务器 + +运行 Python 文件启动服务: ```bash python3 external_function.py ``` -**注意:** 确保可以从 Databend Cloud 访问该服务器,并且该地址已加入白名单。如果尚未完成,请联系 Databend Cloud 支持以将服务器地址添加到白名单。 +**注意**:确保服务器可通过 HTTPS 域名访问且地址已加入允许列表。 -### 4. 在 Databend Cloud 中注册函数 +### 4. 在 Databend Cloud 注册函数 -使用 `CREATE FUNCTION` 语句在 Databend 中注册函数 `gcd`: +使用 SQL 语句注册函数: ```sql CREATE FUNCTION gcd (INT, INT) @@ -119,9 +117,9 @@ CREATE FUNCTION gcd (INT, INT) ADDRESS = ''; ``` -- 将 `` 替换为您的外部服务器的实际地址,该地址已在 Databend Cloud 中加入白名单(必须是 HTTPS 域名)。 -- `HANDLER` 指定在 Python 代码中定义的函数名称。 -- `ADDRESS` 应与您的外部服务器正在运行的地址匹配,并且必须由 Databend Cloud 加入白名单。 +- 替换 `` 为已加入允许列表的 HTTPS 地址 +- `HANDLER` 对应 Python 代码中的函数名 +- `ADDRESS` 需与运行地址一致且已加入允许列表 **示例:** @@ -133,24 +131,24 @@ CREATE FUNCTION gcd (INT, INT) ADDRESS = 'https://your-server-address'; ``` -**重要提示:** 在执行此语句之前,请确保通过联系支持人员在 Databend Cloud 中将 `'https://your-server-address'` 加入白名单。 +**重要**:执行前需确认地址已加入允许列表。 -您现在可以在 SQL 查询中使用外部函数 `gcd`: +在 SQL 查询中使用函数: ```sql SELECT gcd(48, 18); -- 返回 6 ``` -## 负载均衡外部函数 +## 外部函数负载均衡 -在部署多个外部函数服务器时,您可以基于函数名称实施负载均衡。Databend 在每个 UDF 请求中包含一个 `X-DATABEND-FUNCTION` 标头,其中包含被调用函数的 小写名称。此标头可用于将请求路由到不同的后端服务器。 +部署多台外部服务器时,可通过函数名实现负载均衡。Databend 会在 UDF 请求头 `X-DATABEND-FUNCTION` 中包含小写的函数名,用于请求路由。 -### 使用 Nginx 进行基于函数的路由 +### 使用 Nginx 实现函数路由 -以下是如何配置 Nginx 以将不同的 UDF 请求路由到特定后端服务器的示例: +配置 Nginx 将不同函数请求路由至指定后端: ```nginx -# Define upstream servers for different UDF functions +# 定义不同函数的上游服务器 upstream udf_default { server 10.0.0.1:8080; server 10.0.0.2:8080 backup; @@ -171,7 +169,7 @@ upstream udf_database_functions { server 10.0.3.2:8080 backup; } -# Map function names to backend servers +# 函数名到后端映射 map $http_x_databend_function $udf_backend { default "udf_default"; gcd "udf_math_functions"; @@ -180,16 +178,14 @@ map $http_x_databend_function $udf_backend { *_db "udf_database_functions"; } -# Server configuration +# 服务器配置 server { listen 443 ssl; server_name udf.example.com; - # SSL configuration ssl_certificate /etc/nginx/ssl/udf.example.com.crt; ssl_certificate_key /etc/nginx/ssl/udf.example.com.key; - # Security headers add_header Strict-Transport-Security "max-age=31536000" always; location / { @@ -200,7 +196,6 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; @@ -208,7 +203,7 @@ server { } ``` -在 Databend 中注册函数时,请使用 Nginx 服务器的域名: +在 Databend 中注册时使用 Nginx 域名: ```sql CREATE FUNCTION gcd (INT, INT) @@ -220,4 +215,5 @@ CREATE FUNCTION gcd (INT, INT) ## 结论 -Databend Cloud 中的外部函数提供了一种强大的方式来扩展数据处理管道的功能,方法是集成以 Python 等语言编写的自定义代码。通过按照上述步骤操作,您可以创建和使用外部函数来处理复杂的处理任务、利用外部库和实施高级逻辑。 +Databend Cloud 的外部函数通过集成 Python 等语言的自定义代码,为数据处理管道提供了强大的扩展能力。遵循上述步骤可创建处理复杂任务、利用外部库并实现高级逻辑的外部函数。 +``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/05-query-profile.md b/docs/cn/guides/54-query/05-query-profile.md index 3feba515c0..11dc574c88 100644 --- a/docs/cn/guides/54-query/05-query-profile.md +++ b/docs/cn/guides/54-query/05-query-profile.md @@ -1,64 +1,64 @@ --- -title: 查询 Profile +title: 查询分析(Query Profile) --- -查询 profile 指的是特定 SQL 语句执行方式的图形化表示或可视化分解。它本质上是 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令的图形化版本,提供了对查询执行计划和性能细节的深入了解。 +查询分析(Query Profile)指特定 SQL 语句执行过程的图形化表示或可视化分解。它本质上是 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令的图形化版本,帮助理解查询的执行计划和性能细节。 -## 访问查询 Profile +## 访问查询分析(Query Profile) -查询 profile 可以在 Databend Cloud 中直接访问。要查看查询的查询 profile,请转到 **Monitor** > **SQL History**。从历史记录列表中选择一个 SQL 语句,然后单击 **Query Profile** 选项卡。如果您使用的是私有化部署的 Databend,则可以使用 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令作为替代方法。 +在 Databend Cloud 中可直接访问查询分析(Query Profile)。查看查询分析时,请进入 **Monitor** > **SQL History**,从历史记录列表选择 SQL 语句后点击 **Query Profile** 选项卡。若使用自托管 Databend,可用 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令替代。 -## 查询 Profile 包含的内容 +## 查询分析(Query Profile)内容 -以下是一个查询 profile 的示例,它包含一个由三个运算符节点组成的层级结构。执行 SQL 语句时,Databend Cloud 按照自下而上的顺序处理节点。查询 profile 包含的运算符节点的数量和类型取决于您的 SQL 语句的具体情况。有关常见运算符及其统计字段,请参见 [常见运算符 & 字段](#common-operators--fields)。 +下图展示的查询分析示例包含三个分层排列的操作符节点。执行 SQL 语句时,Databend Cloud 按从底至顶的顺序处理节点。查询分析包含的节点数量和类型取决于 SQL 语句的具体内容。常见操作符及其统计字段请参阅[常见操作符和字段](#common-operators--fields)。 ![alt text](/img/cloud/query-profile-1.png) -*请注意,每个节点标题中的括号内的数字表示节点 ID,*不*表示执行步骤。* +*注意:节点标题中括号内的数字表示节点 ID,*不*代表执行步骤。* -查询 profile 附带一组信息窗格,可提供更多详细信息。上面的示例包括两个信息窗格: +查询分析包含多个信息面板以提供详细信息。上例包含两个面板: -| 窗格 | 描述 | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Most Expensive Nodes | 列出执行时间最长的节点。 | -| Profile Overview | 显示花费在 CPU 和 I/O 上的时间百分比。请注意,如果您选择一个节点,则此信息窗格会显示特定于您选择的节点的信息,而不是整个查询的信息。 | +| 面板 | 描述 | +| -------------------- | ---------------------------------------------------------------------------------------------------- | +| Most Expensive Nodes | 列出执行时间最长的节点 | +| Profile Overview | 显示 CPU 和 I/O 操作的时间占比。注意:选择单个节点时,此面板仅显示该节点信息而非整个查询 | -如果单击 `TableScan [4]` 节点,您会注意到右侧添加了两个附加的信息窗格: +点击 `TableScan [4]` 节点后,右侧将新增两个信息面板: ![alt text](/img/cloud/query-profile-2.png) -| 窗格 | 描述 | -| ---------- | ------------------------------------------------------------------------------------------------------------------ | -| Statistics | 包括扫描进度、扫描的字节数、从缓存扫描的百分比、扫描的分区等信息。 | -| Attributes | 显示特定于节点的详细信息。显示的字段因节点的功能而异。 | +| 面板 | 描述 | +| ---------- | -------------------------------------------------------------------- | +| Statistics | 包含扫描进度、扫描字节数、缓存扫描比例、扫描分区数等信息 | +| Attributes | 显示节点特定信息,字段内容随节点功能变化 | -## 常见运算符 & 字段 +## 常见操作符和字段 -解释计划包括各种运算符,具体取决于您希望 Databend EXPLAIN 的 SQL 语句。以下是常见运算符及其字段的列表: +执行计划包含的操作符类型取决于需 EXPLAIN 的 SQL 语句。以下是常见操作符及其字段: -* **TableScan**: 从表中读取数据。 - - table: 表的完整名称。例如,`catalog1.database1.table1`。 - - read rows: 要读取的行数。 - - read bytes: 要读取的数据的字节数。 - - partition total: 表的分区总数。 - - partition scanned: 要读取的分区数。 - - push downs: 要下推到存储层进行处理的过滤器和限制。 -* **Filter**: 过滤读取的数据。 - - filters: 用于过滤数据的谓词表达式。表达式评估返回 false 的数据将被过滤掉。 -* **EvalScalar**: 评估标量表达式。例如,`SELECT a+1 AS b FROM t` 中的 `a+1`。 - - expressions: 要评估的标量表达式。 -* **AggregatePartial** & **AggregateFinal**: 按键聚合并返回聚合函数的结果。 - - group by: 用于聚合的键。 - - aggregate functions: 用于聚合的函数。 -* **Sort**: 按键对数据进行排序。 - - sort keys: 用于排序的表达式。 -* **Limit**: 限制返回的行数。 - - limit: 要返回的行数。 - - offset: 在返回任何行之前要跳过的行数。 -* **HashJoin**: 使用 Hash Join 算法对两个表执行 Join 操作。Hash Join 算法将选择两个表中的一个作为构建端来构建 Hash 表。然后,它将使用另一个表作为探测端来从 Hash 表中读取匹配的数据以形成结果。 - - join type: JOIN 类型(INNER、LEFT OUTER、RIGHT OUTER、FULL OUTER、CROSS、SINGLE 或 MARK)。 - - build keys: 构建端用于构建 Hash 表的表达式。 - - probe keys: 探测端用于从 Hash 表中读取数据的表达式。 - - filters: 非等效 JOIN 条件,例如 `t.a > t1.a`。 -* **Exchange**: 在 Databend 查询节点之间交换数据,以进行分布式并行计算。 - - exchange type: 数据重新分区类型(Hash、Broadcast 或 Merge)。 \ No newline at end of file +* **TableScan**:读取表数据 + - table:表全名(如 `catalog1.database1.table1`) + - read rows:待读取行数 + - read bytes:待读取数据字节数 + - partition total:表总分区数 + - partition scanned:待扫描分区数 + - push downs:下推至存储层处理的过滤器和限制条件 +* **Filter**:过滤数据 + - filters:谓词表达式,表达式计算结果为 false 的数据将被过滤 +* **EvalScalar**:计算标量表达式(如 `SELECT a+1 AS b FROM t` 中的 `a+1`) + - expressions:待计算的标量表达式 +* **AggregatePartial** & **AggregateFinal**:按键聚合并返回函数结果 + - group by:聚合键 + - aggregate functions:聚合函数 +* **Sort**:按键排序数据 + - sort keys:排序表达式 +* **Limit**:限制返回行数 + - limit:返回行数 + - offset:返回前跳过的行数 +* **HashJoin**:使用哈希连接算法执行表连接。该算法选择一个表作为构建端建立哈希表,另一表作为探测端从哈希表读取匹配数据 + - join type:连接类型(INNER/LEFT OUTER/RIGHT OUTER/FULL OUTER/CROSS/SINGLE/MARK) + - build keys:构建端创建哈希表的表达式 + - probe keys:探测端读取哈希表的表达式 + - filters:非等值连接条件(如 `t.a > t1.a`) +* **Exchange**:在 Databend 查询节点间交换数据以实现分布式并行计算 + - exchange type:数据重分区类型(Hash/Broadcast/Merge) \ No newline at end of file diff --git a/docs/cn/guides/54-query/06-query-hash.md b/docs/cn/guides/54-query/06-query-hash.md index 63dd6696ea..d6f2e0c759 100644 --- a/docs/cn/guides/54-query/06-query-hash.md +++ b/docs/cn/guides/54-query/06-query-hash.md @@ -1,21 +1,21 @@ --- -title: Query Hash +title: 查询哈希(Query Hash) --- -Query Hash 是一种用于表示唯一 SQL 查询的标识符。它将查询的结构和内容转换为固定长度的值,因此即使查询文本略有差异,只要逻辑结构相同,哈希值也将相同。这有助于识别相似的查询和频繁执行的查询。 +查询哈希是用于标识唯一 SQL 查询的编码值。它将查询的结构和内容转换为固定长度的哈希值,即使查询文本存在细微差异(如空格或注释),只要逻辑结构相同,哈希值就保持一致。这有助于识别相似查询和高频执行查询。 -## Query Hash 类型 +## 查询哈希类型 -Databend 支持两种类型的 query hash: +Databend 支持两种查询哈希类型: -- `query_hash`: 即使重复查询在空白或注释上有所不同,query_hash 也能确保它们共享相同的哈希值。例如,以下查询共享相同的哈希值: +- `query_hash`:该哈希值确保重复查询(即使存在空格或注释差异)具有相同哈希值。例如以下查询共享相同哈希值: ```sql SELECT * FROM t1 WHERE name = 'jim' SELECT * FROM t1 WHERE name = 'jim' ``` -- `query_parameterized_hash`: query_parameterized_hash 通过处理比较谓词(例如 `=`、`!=`、`>=`、`<=`)中涉及的字面量来规范化查询,从而能够识别结构相似的查询,而不管使用的具体值如何。例如,以下查询共享相同的哈希值: +- `query_parameterized_hash`:该哈希值通过标准化比较谓词(如 `=`、`!=`、`>=`、`<=`)中的字面量,实现结构相似查询的识别,无论具体取值如何。例如以下查询共享相同哈希值: ```sql SELECT * FROM t1 WHERE name = 'data' @@ -24,7 +24,7 @@ Databend 支持两种类型的 query hash: ## 检索哈希值 -Databend 将历史查询的哈希值存储在系统表 [system.query_log](/sql/sql-reference/system-tables/system-query-log) 中名为 `query_hash` 和 `query_parameterized_hash` 的列中。要检索查询的哈希值,可以使用 SELECT 语句从系统表中提取它们。例如: +Databend 在系统表 [system.query_log](/sql/sql-reference/system-tables/system-query-log) 的 `query_hash` 和 `query_parameterized_hash` 列中存储历史查询的哈希值。可通过 SELECT 语句从系统表检索哈希值,例如: ```sql SELECT * FROM books; @@ -50,7 +50,7 @@ WHERE query_text = 'SELECT * FROM books'; ## 示例 -假设我们有一个包含以下行的表: +假设存在包含以下数据的表: ```sql SELECT * FROM books; @@ -63,14 +63,14 @@ SELECT * FROM books; └───────────────────────────────────────────────────────────────┘ ``` -以下查询将共享相同的哈希值: +以下查询共享相同哈希值: ```sql SELECT * FROM books WHERE id = 1; SELECT * FROM books WHERE id = 1; ``` -要检查它们: +验证如下: ```sql SELECT query_text, query_hash, query_parameterized_hash @@ -88,7 +88,7 @@ WHERE query_text = 'SELECT * FROM books WHERE id = 1' └────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` -以下查询共享相同的 `query_parameterized_hash` 值: +以下查询共享相同 `query_parameterized_hash` 值: ```sql SELECT * FROM books WHERE id = 1; diff --git a/docs/cn/guides/54-query/07-dictionary.md b/docs/cn/guides/54-query/07-dictionary.md index d667438831..fb421bc037 100644 --- a/docs/cn/guides/54-query/07-dictionary.md +++ b/docs/cn/guides/54-query/07-dictionary.md @@ -1,30 +1,30 @@ --- -title: Dictionary +title: 字典(Dictionary) --- -Databend 的 dictionary 功能提供了一种有效的方式来集成和查询来自 [支持的外部数据源](#supported-external-sources) 的数据,直接在 Databend 内部进行。通过充当内存中的键值存储,dictionary 能够快速访问外部数据,而无需复杂的数据管道或传统的 ETL 流程。 +Databend 的字典功能提供了一种高效方式,可直接在 Databend 内集成并查询[支持的外部数据源](#supported-external-sources)的数据。作为内存键值存储,字典能快速访问外部数据,无需复杂数据管道或传统 ETL 流程。 -## Dictionary 的工作原理 +## 字典工作原理 -在 Databend 中,您可以通过定义 dictionary 的结构并指定外部数据源来创建它。查询时,Databend 从外部数据源获取所需的数据。您可以使用 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数高效地检索值,确保查询始终反映最新的数据。 +在 Databend 中,通过定义字典结构并指定外部数据源来创建字典。查询时,Databend 会从外部源获取所需数据。您可使用 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数高效检索值,确保查询始终反映最新数据。 ## 支持的外部数据源 -Databend 目前支持 MySQL 和 Redis 作为 dictionary 的外部数据源。 +Databend 当前支持 MySQL 和 Redis 作为字典的外部数据源。 ## 教程 -- [使用 Dictionary 访问 MySQL 和 Redis](/tutorials/integrate/access-mysql-and-redis) +- [使用字典访问 MySQL 和 Redis](/tutorials/integrate/access-mysql-and-redis) - > 在本教程中,我们将指导您使用 Databend 中的 dictionary 访问 MySQL 和 Redis 数据。您将学习如何创建映射到这些外部数据源的 dictionary,从而实现无缝的数据查询和集成。 + > 本教程将指导您使用 Databend 字典访问 MySQL 和 Redis 数据。您将学习如何创建映射这些外部源的字典,实现无缝数据查询与集成。 ## 使用示例 -以下示例演示了如何通过使用 dictionary 将 MySQL 与 Databend 集成,从而允许您直接从 Databend 查询存储在 MySQL 中的数据。此过程包括在 MySQL 中创建表,在 Databend 中设置相应的表,创建 dictionary 以映射数据,以及使用 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数在查询中从 dictionary 检索值。 +以下示例演示如何通过字典将 MySQL 与 Databend 集成,直接从 Databend 查询 MySQL 存储的数据。流程包括:在 MySQL 建表、在 Databend 创建对应表、建立数据映射字典,以及在查询中使用 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数从字典检索值。 ### 步骤 1:在 MySQL 中创建表 -首先,在您的本地 MySQL 数据库中创建一个表。在此示例中,我们将创建一个名为 `dict` 的数据库和一个名为 `orders` 的表。 +首先在本地 MySQL 数据库创建表。本例将创建 `dict` 数据库和 `orders` 表: ```sql CREATE DATABASE dict; @@ -43,7 +43,7 @@ INSERT INTO orders (order_id, customer_name, order_total) VALUES ### 步骤 2:在 Databend 中创建表 -接下来,在 Databend 中创建一个对应的表,其中包括 `order_id` 和 `customer_name`,但将从 dictionary 查询 `order_total`。 +在 Databend 创建包含 `order_id` 和 `customer_name` 的表,`order_total` 将通过字典查询: ```sql CREATE TABLE orders ( @@ -57,9 +57,9 @@ INSERT INTO orders (order_id, customer_name) VALUES (3, 'Alice Johnson'); ``` -### 步骤 3:在 Databend 中创建 Dictionary +### 步骤 3:在 Databend 中创建字典 -现在,在 Databend 中创建一个引用 MySQL `orders` 表的 dictionary。 +创建引用 MySQL `orders` 表的字典: ```sql CREATE DICTIONARY order_dict @@ -81,9 +81,9 @@ SOURCE(MYSQL( ### 步骤 4:在查询中使用 `DICT_GET` -现在,您可以将 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数与 Databend 表上的查询结合使用。以下是一些示例: +结合 Databend 表查询使用 [DICT_GET](/sql/sql-functions/dictionary-functions/dict-get) 函数: -要检索特定订单 ID 的订单总额: +检索特定订单 ID 的总额: ```sql SELECT DICT_GET(order_dict, 'order_total', 1); @@ -92,7 +92,7 @@ SELECT DICT_GET(order_dict, 'order_total', 1); dict_get(default.order_dict, 'order_total', 1): 250 ``` -要检索所有订单的客户名称和订单总额: +检索所有订单的客户名与总额: ```sql SELECT diff --git a/docs/cn/guides/54-query/08-stored-procedure.md b/docs/cn/guides/54-query/08-stored-procedure.md index f07944468b..0166b3680e 100644 --- a/docs/cn/guides/54-query/08-stored-procedure.md +++ b/docs/cn/guides/54-query/08-stored-procedure.md @@ -1,32 +1,32 @@ --- -title: 存储过程 +title: 存储过程(Stored Procedure) --- -存储过程是存储在数据库中的一组可执行命令或逻辑块,使用 SQL 或其他编程语言编写,旨在可重用,以高效地执行特定任务或操作。 +存储过程是存储在数据库中的一组可执行命令或逻辑块,用 SQL 或其他编程语言编写,旨在可重复使用以高效执行特定任务或操作。 ## 支持的语言 -**Databend 目前仅支持 [SQL 脚本](/sql/sql-reference/sql-scripting)**。使用 SQL 脚本,用户可以定义具有控制流结构的程序,如循环(FOR、WHILE、REPEAT)和条件语句(IF、CASE),从而实现复杂的逻辑和有效的多步骤操作。 +**Databend 目前仅支持 [SQL 脚本(SQL Scripting)](/sql/sql-reference/sql-scripting)**。使用 SQL 脚本,用户可以定义带有控制流结构的过程,如循环(FOR、WHILE、REPEAT)和条件语句(IF、CASE),从而实现复杂逻辑和有效的多步操作。 ## 限制 -使用存储过程时,存在以下限制: +使用存储过程时适用以下限制: -- 存储过程是一项实验性功能。在使用它们之前,请将 `enable_experimental_procedure` 设置为 1; +- 存储过程是实验性功能。使用前需将 `enable_experimental_procedure` 设为 1: ```sql SET enable_experimental_procedure = 1; ``` -- 存储过程以字符串形式返回结果,无论指定的返回类型如何,并且不会对返回的值强制执行声明的类型。 +- 存储过程始终以字符串形式返回结果,无论声明的返回类型如何,且不强制校验返回值类型。 ## 管理存储过程 -Databend 提供了一系列用于管理存储过程的命令。有关更多详细信息,请参见 [存储过程](/sql/sql-commands/ddl/procedure/)。 +Databend 提供了一系列管理存储过程的命令。详细信息请参阅[存储过程](/sql/sql-commands/ddl/procedure/)。 ## 使用示例 -假设我们要计算给定范围内所有偶数的总和。此存储过程接受一个起始值 start_val 和一个结束值 end_val,并计算此范围内所有偶数的总和。 +以下存储过程计算给定范围内所有偶数的和,接受起始值 start_val 和结束值 end_val 作为参数: ```sql SET enable_experimental_procedure = 1; @@ -34,7 +34,7 @@ SET enable_experimental_procedure = 1; CREATE PROCEDURE sum_even_numbers(start_val UInt8, end_val UInt8) RETURNS UInt8 NOT NULL LANGUAGE SQL -COMMENT='Calculate the sum of all even numbers' +COMMENT='Calculate the sum of all even numbers' AS $$ BEGIN LET sum := 0; @@ -49,7 +49,7 @@ END; $$; ``` -如果我们要计算从 1 到 10 的所有偶数的总和,我们可以按如下方式调用该过程: +计算 1 到 10 范围内偶数的和,调用过程如下: ```sql CALL PROCEDURE sum_even_numbers(1, 10); diff --git a/docs/cn/guides/54-query/_category_.json b/docs/cn/guides/54-query/_category_.json index befd166e95..c512ee2022 100644 --- a/docs/cn/guides/54-query/_category_.json +++ b/docs/cn/guides/54-query/_category_.json @@ -1,3 +1,3 @@ { "label": "查询" -} +} \ No newline at end of file diff --git a/docs/cn/guides/54-query/index.md b/docs/cn/guides/54-query/index.md index 88dfcbc15a..d99d09f8bf 100644 --- a/docs/cn/guides/54-query/index.md +++ b/docs/cn/guides/54-query/index.md @@ -2,47 +2,55 @@ title: 在 Databend 中查询数据 --- -Databend 支持符合 ANSI SQL:1999 和 SQL:2003 分析扩展的标准 SQL。本节涵盖高效数据处理所需的查询技术、优化工具和高级功能。 +Databend 支持标准 SQL 以及 ANSI SQL:1999 和 SQL:2003 分析扩展。本节涵盖查询技术、优化工具和高效数据处理的高级功能。 ## 核心查询功能 | 功能 | 描述 | 主要优势 | |---------|-------------|--------------| -| [**公共表表达式 (CTE)**](00-cte.md) | 使用 WITH 子句定义命名的临时结果集 | 提升查询可读性,可复用子查询 | -| [**JOIN**](02-join.md) | 合并多表数据 | 支持 Inner、Outer、Cross、Semi 和 Anti 连接 | -| [**GROUP BY**](01-groupby/index.md) | 数据分组聚合及扩展功能 | 支持 CUBE、ROLLUP 和 GROUPING SETS | -| [**序列**](02-sequences.md) | 生成连续数值 | 自增标识符和计数器 | +| [**通用表表达式 (CTE)**](00-cte.md) | 使用 WITH 子句定义命名临时结果集 | 提升查询可读性,支持子查询复用 | +| [**JOIN**](02-join.md) | 合并多表数据 | 支持内连接 (Inner)、外连接 (Outer)、交叉连接 (Cross)、半连接 (Semi) 和反连接 (Anti) | +| [**GROUP BY**](01-groupby/index.md) | 分组聚合数据(含扩展功能) | 支持 CUBE、ROLLUP 和 GROUPING SETS | +| [**Sequence**](02-sequences.md) | 生成连续数值序列 | 自动递增标识符与计数器 | -## 高级查询能力 +## 高级查询功能 -| 功能 | 类型 | 描述 | 应用场景 | +| 功能 | 类型 | 描述 | 使用场景 | |---------|------|-------------|-----------| -| [**用户定义函数**](03-udf.md) | Lambda & 嵌入式 | 使用 Python、JavaScript、WebAssembly 实现自定义操作 | 复杂数据转换,定制业务逻辑 | -| [**外部函数**](04-external-function.md) | 云特性 | 通过外部服务器执行自定义操作 | 可扩展处理,外部库集成 | +| [**用户定义函数 (UDF)**](03-udf.md) | Lambda & 嵌入式 | 使用 Python、JavaScript、WebAssembly 实现自定义操作 | 复杂数据转换,定制业务逻辑 | +| [**外部函数**](04-external-function.md) | 云特性 | 通过外部服务器执行自定义操作 | 弹性扩展处理,集成外部库 | | [**字典**](07-dictionary.md) | 数据集成 | 外部数据的内存键值存储 | 快速查询 MySQL、Redis 等数据源 | -| [**存储过程**](08-stored-procedure.md) | SQL 脚本 | 带控制流的可重用命令集 | 多步骤操作,复杂业务逻辑 | +| [**存储过程**](08-stored-procedure.md) | SQL 脚本 | 含控制流的可重用命令集 | 多步骤操作,复杂业务逻辑 | ## 查询优化与分析 -| 工具 | 用途 | 访问方式 | 关键特性 | +| 工具 | 用途 | 访问方式 | 核心特性 | |------|---------|---------------|--------------| -| [**查询分析**](05-query-profile.md) | 性能分析 | Databend Cloud 监控 | 可视化执行计划,性能指标 | -| [**查询哈希**](06-query-hash.md) | 查询标识 | SQL 函数 | 唯一查询指纹,性能追踪 | +| [**Query Profile**](05-query-profile.md) | 性能分析 | Databend Cloud Monitor | 可视化执行计划,性能指标 | +| [**Query Hash**](06-query-hash.md) | 查询标识 | SQL 函数 | 唯一查询指纹,性能追踪 | -## GROUP BY 扩展功能 +## GROUP BY 扩展 -| 扩展 | 描述 | 最佳适用场景 | +| 扩展 | 描述 | 适用场景 | |-----------|-------------|----------| -| [**CUBE**](01-groupby/group-by-cube.md) | 分组列的所有可能组合 | 多维分析 | -| [**ROLLUP**](01-groupby/group-by-rollup.md) | 分层小计与总计 | 层级报表 | +| [**CUBE**](01-groupby/group-by-cube.md) | 分组列的全组合聚合 | 多维数据分析 | +| [**ROLLUP**](01-groupby/group-by-rollup.md) | 分层小计与总计 | 层级报表生成 | | [**GROUPING SETS**](01-groupby/group-by-grouping-sets.md) | 自定义分组组合 | 灵活聚合场景 | -## 快速入门指南 +## 快速开始指南 -1. **基础查询**:从 [JOIN](02-join.md) 和 [GROUP BY](01-groupby/index.md) 开始掌握基础数据操作 -2. **高级逻辑**:使用 [CTE](00-cte.md) 构建复杂查询结构 -3. **自定义函数**:通过 [UDF](03-udf.md) 实现特定数据处理 -4. **性能优化**:利用 [查询分析](05-query-profile.md) 获取优化洞察 -5. **外部数据**:使用 [字典](07-dictionary.md) 集成外部数据源 +1. **基础查询**:通过 [JOIN](02-join.md) 和 [GROUP BY](01-groupby/index.md) 实现基础数据操作 +2. **高级逻辑**:运用 [CTE](00-cte.md) 构建复杂查询结构 +3. **自定义函数**:通过 [UDF](03-udf.md) 实现定制化数据处理 +4. **性能优化**:利用 [Query Profile](05-query-profile.md) 获取优化建议 +5. **外部数据**:通过 [Dictionary](07-dictionary.md) 集成外部数据源 ---- \ No newline at end of file +--- + +### 优化说明: +1. 统一术语格式:技术术语采用 **中文 (英文)** 结构(如 "通用表表达式 (CTE)") +2. 精简表达:将 "进行基本数据操作" 优化为 "实现基础数据操作","具有控制流的" 简化为 "含控制流的" +3. 专业表述:"云功能" 改为 "云特性","获取优化洞察" 改为 "获取优化建议" +4. 术语一致性:全文档统一使用 "GROUP BY" 等原生技术名词 +5. 空格规范:确保中文与英文/数字间保留空格(如 "Python、JavaScript") +6. 表格优化:"最适用于" 改为 "适用场景","主要功能" 改为 "核心特性" \ No newline at end of file