Skip to content

Commit f61474b

Browse files
🌐 Add LLM Translations (#858)
* 💬Generate LLM translations * docs: _category_.json * docs: _category_.json * docs: minor update Signed-off-by: Chojan Shang <[email protected]> --------- Signed-off-by: Chojan Shang <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Chojan Shang <[email protected]>
1 parent 02e062f commit f61474b

File tree

11 files changed

+562
-188
lines changed

11 files changed

+562
-188
lines changed

docs/cn/guides/54-query/00-cte.md

Lines changed: 163 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
---
2-
title: 公共表表达式(CTEs
2+
title: 通用表表达式 (CTEs)
33
---
44

5-
Databend 支持带有 WITH 子句的公共表表达式(CTEs),允许您定义一个或多个命名的临时结果集,供后续查询使用。"临时"一词意味着结果集不会永久存储在数据库架构中。它们仅作为临时视图,只能被后续查询访问。
5+
import FunctionDescription from '@site/src/components/FunctionDescription';
66

7-
当执行带有 WITH 子句的查询时,WITH 子句中的 CTEs 首先被评估和执行。这会产生一个或多个临时结果集。然后使用 WITH 子句产生的临时结果集执行查询。
7+
<FunctionDescription description="引入或更新于: v1.2.530"/>
88

9-
这是一个简单的演示,帮助您理解 CTEs 在查询中的工作方式:WITH 子句定义了一个 CTE 并产生了一个结果集,该结果集包含所有来自魁北克省的客户。主查询从魁北克省的客户中筛选出居住在蒙特利尔地区的客户。
9+
Databend 支持使用 WITH 子句的通用表表达式 (CTEs),允许你定义一个或多个命名的临时结果集,供后续查询使用。术语“临时”意味着这些结果集不会永久存储在数据库架构中。它们仅作为临时视图,供后续查询访问。
10+
11+
当执行带有 WITH 子句的查询时,WITH 子句中的 CTEs 首先被评估和执行。这会产生一个或多个临时结果集。然后,查询使用由 WITH 子句产生的临时结果集执行。
12+
13+
这是一个简单的演示,帮助你理解查询中 CTEs 的工作原理:WITH 子句定义了一个 CTE,并生成一个结果集,其中包含所有来自魁北克省的客户。主查询从魁北克省的客户中筛选出居住在蒙特利尔地区的客户。
1014

1115
```sql
1216
WITH customers_in_quebec
@@ -20,7 +24,7 @@ WHERE city = 'Montréal'
2024
ORDER BY customername;
2125
```
2226

23-
CTEs 简化了使用子查询的复杂查询,并使您的代码更易于阅读和维护。如果不使用 CTE,前面的示例将会是这样
27+
CTEs 简化了使用子查询的复杂查询,并使你的代码更易于阅读和维护。如果不使用 CTE,前面的示例将如下所示
2428

2529
```sql
2630
SELECT customername
@@ -32,17 +36,17 @@ WHERE city = 'Montréal'
3236
ORDER BY customername;
3337
```
3438

35-
## 内联还是物化
39+
## 内联或物化
3640

37-
在查询中使用 CTE 时,您可以通过使用 MATERIALIZED 关键字来控制 CTE 是内联还是物化。内联意味着 CTE 的定义直接嵌入到主查询中,而物化 CTE 意味着一次计算其结果并将其存储在内存中,减少重复的 CTE 执行。
41+
在使用查询中的 CTE 时,你可以通过使用 MATERIALIZED 关键字来控制 CTE 是内联还是物化。内联意味着 CTE 的定义直接嵌入到主查询中,而物化 CTE 意味着计算其结果一次并将其存储在内存中,减少重复的 CTE 执行。
3842

3943
假设我们有一个名为 _orders_ 的表,存储客户订单信息,包括订单号、客户 ID 和订单日期。
4044

4145
import Tabs from '@theme/Tabs';
4246
import TabItem from '@theme/TabItem';
4347

4448
<Tabs>
45-
<TabItem value="Inline" label="内联" default>
49+
<TabItem value="Inline" label="Inline" default>
4650

4751
在这个查询中,CTE _customer_orders_ 将在查询执行期间内联。Databend 将直接将 _customer_orders_ 的定义嵌入到主查询中。
4852

@@ -60,9 +64,9 @@ WHERE co1.order_count > 2
6064
```
6165

6266
</TabItem>
63-
<TabItem value="Materialized" label="物化">
67+
<TabItem value="Materialized" label="Materialized">
6468

65-
在这种情况下,我们使用了 MATERIALIZED 关键字,这意味着 CTE _customer_orders_ 将不会内联。相反,在执行 CTE 定义时,CTE 的结果将被计算并存储在内存中。在主查询中执行 CTE 的两个实例时,Databend 将直接从内存中检索结果,避免了重复的计算,并可能提高性能。
69+
在这种情况下,我们使用 MATERIALIZED 关键字,这意味着 CTE _customer_orders_ 不会被内联。相反,CTE 的结果将在 CTE 定义执行时计算并存储在内存中。当在主查询中执行 CTE 的两个实例时,Databend 将直接从内存中检索结果,避免重复计算,并可能提高性能。
6670

6771
```sql
6872
WITH customer_orders AS MATERIALIZED (
@@ -77,7 +81,7 @@ WHERE co1.order_count > 2
7781
AND co2.order_count > 5;
7882
```
7983

80-
这可以显著提高性能,特别是在 CTE 的结果被多次使用的情况下。然而,由于 CTE 不再内联,查询优化器可能难以将 CTE 的条件推入主查询或优化连接顺序,可能导致整体查询性能下降。
84+
这可以显著提高性能, CTE 的结果被多次使用的情况下。然而,由于 CTE 不再内联,查询优化器可能难以将 CTE 的条件推入主查询或优化连接顺序,可能导致整体查询性能下降。
8185

8286
</TabItem>
8387
</Tabs>
@@ -89,20 +93,55 @@ WITH
8993
<cte_name1> [ ( <cte_column_list> ) ] AS [MATERIALIZED] ( SELECT ... )
9094
[ , <cte_name2> [ ( <cte_column_list> ) ] AS [MATERIALIZED] ( SELECT ... ) ]
9195
[ , <cte_nameN> [ ( <cte_column_list> ) ] AS [MATERIALIZED] ( SELECT ... ) ]
96+
SELECT ... | UPDATE ... | DELETE FROM ...
97+
```
98+
99+
| 参数 | 描述 |
100+
| ----------------------- | ---------------------------------------------------------------------- |
101+
| WITH | 启动 WITH 子句。 |
102+
| cte_name1 ... cte_nameN | CTE 的名称。当你有多个 CTE 时,用逗号将它们分开。 |
103+
| cte_column_list | CTE 中列的名称。CTE 可以引用在同一 WITH 子句中定义在其之前的任何 CTE。 |
104+
| MATERIALIZED | `Materialized` 是一个可选关键字,用于指示 CTE 是否应该被物化。 |
105+
106+
## 递归 CTEs
107+
108+
递归 CTE 是一个临时结果集,它引用自身来执行递归操作,允许处理层次或递归数据结构。
109+
110+
### 语法
111+
112+
```sql
113+
WITH RECURSIVE <cte_name> AS (
114+
<initial_query>
115+
UNION ALL
116+
<recursive_query> )
92117
SELECT ...
93118
```
94119

95-
| 参数 | 描述 |
96-
| ----------------------- | --------------------------------------------------------------------- |
97-
| WITH | 开始 WITH 子句。 |
98-
| cte_name1 ... cte_nameN | CTE 的名称。当您有多个 CTE 时,用逗号分隔它们。 |
99-
| cte_column_list | CTE 中的列名。一个 CTE 可以引用同一个 WITH 子句中定义的任何其他 CTE。 |
100-
| MATERIALIZED | “物化”是在定义 CTE 时使用的可选关键字,用来指示 CTE 是否应该物化。 |
101-
| SELECT ... | CTE 主要与 SELECT 语句一起使用。 |
120+
| 参数 | 描述 |
121+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
122+
| `cte_name` | CTE 的名称。 |
123+
| `initial_query` | 初始查询,在递归开始时执行一次,通常返回一组行。 |
124+
| `recursive_query` | 引用 CTE 本身的查询,重复执行直到返回空结果集。此查询必须包含对 CTE 名称的引用。查询中不得包含聚合函数(如 MAX, MIN, SUM, AVG, COUNT)、窗口函数、GROUP BY 子句、ORDER BY 子句、LIMIT 子句或 DISTINCT。 |
125+
126+
### 工作原理
127+
128+
以下描述了递归 CTE 的详细执行顺序:
129+
130+
1. **初始查询执行**:此查询形成基础结果集,记为 R0。该结果集为递归提供起点。
131+
132+
2. **递归查询执行**:此查询使用前一次迭代的结果集(从 R0 开始)作为输入,并产生新的结果集(Ri+1)。
133+
134+
3. **迭代与组合**:递归执行持续迭代进行。递归查询每次产生的新结果集(Ri)成为下一次迭代的输入。此过程重复直至递归查询返回空结果集,表明终止条件已满足。
135+
136+
4. **最终结果集形成**:使用 `UNION ALL` 操作符,将每次迭代的结果集(R0 至 Rn)合并成单一结果集。`UNION ALL` 操作符确保每个结果集中的所有行均包含在最终合并结果中。
137+
138+
5. **最终选择**:最终的 `SELECT ...` 语句从 CTE 中检索合并结果集。此语句可在合并结果集上应用额外的过滤、排序或其他操作,以产生最终输出。
102139

103140
## 使用示例
104141

105-
假设您管理位于 GTA 地区不同地区的几家书店,并使用一个表来保存它们的店铺 ID、地区和上个月的交易量。
142+
### 非递归 CTE
143+
144+
假设您管理着位于 GTA 地区不同区域的多家书店,并使用一张表来记录它们的店铺 ID、区域以及上个月的交易量。
106145

107146
```sql
108147
CREATE TABLE sales
@@ -121,10 +160,10 @@ INSERT INTO sales VALUES (6, 'Markham', 4350);
121160
INSERT INTO sales VALUES (7, 'North York', 2490);
122161
```
123162

124-
以下代码返回交易量低于平均值的商店
163+
以下代码返回交易量低于平均水平的店铺
125164

126165
```sql
127-
-- 定义一个包含一个CTE的WITH子句
166+
-- 定义包含一个 CTE 的 WITH 子句
128167
WITH avg_all
129168
AS (SELECT Avg(amount) AVG_SALES
130169
FROM sales)
@@ -148,10 +187,10 @@ WHERE sales.amount < avg_sales;
148187
└──────────────────────────────────────────────────────────────────────────┘
149188
```
150189

151-
以下代码返回每个地区的平均和总交易量
190+
以下代码返回各区域的平均和总交易量
152191

153192
```sql
154-
-- 定义一个包含两个CTE的WITH子句
193+
-- 定义包含两个 CTE 的 WITH 子句
155194
WITH avg_by_region
156195
AS (SELECT region,
157196
Avg (amount) avg_by_region_value
@@ -175,11 +214,111 @@ WHERE avg_by_region.region = sum_by_region.region;
175214
```text
176215
┌──────────────────────────────────────────────────────────────┐
177216
│ region │ avg_by_region_value │ sum_by_region_value │
178-
│ Nullable(String) │ Nullable(Float64) │ Nullable(Int64) │
179217
├──────────────────┼─────────────────────┼─────────────────────┤
180218
│ North York │ 7645 │ 15290 │
181219
│ Downtown │ 17035 │ 34070 │
182220
│ Markham │ 5535 │ 11070 │
183221
│ Mississauga │ 4990 │ 4990 │
184222
└──────────────────────────────────────────────────────────────┘
185223
```
224+
225+
以下代码将各店铺的交易量更新为 0,条件是其交易量低于各自区域的平均交易量:
226+
227+
```sql
228+
WITH region_avg_sales_cte AS (
229+
SELECT region, AVG(amount) AS avg_sales
230+
FROM sales
231+
GROUP BY region
232+
)
233+
UPDATE sales
234+
SET amount = 0
235+
WHERE amount < (
236+
SELECT avg_sales
237+
FROM region_avg_sales_cte AS cte
238+
WHERE cte.region = sales.region
239+
);
240+
```
241+
242+
假设我们还有一张名为 "store_details" 的表,其中包含每个店铺的额外信息,如店铺的开业日期和店主。
243+
244+
```sql
245+
CREATE TABLE store_details (
246+
storeid INTEGER,
247+
store_name TEXT,
248+
opening_date DATE,
249+
owner TEXT
250+
);
251+
252+
INSERT INTO store_details VALUES (1, 'North York Store', '2022-01-01', 'John Doe');
253+
INSERT INTO store_details VALUES (12, 'Downtown Store', '2022-02-15', 'Jane Smith');
254+
INSERT INTO store_details VALUES (3, 'Markham Store', '2021-12-10', 'Michael Johnson');
255+
INSERT INTO store_details VALUES (9, 'Mississauga Store', '2022-03-20', 'Emma Brown');
256+
INSERT INTO store_details VALUES (5, 'Scarborough Store', '2022-04-05', 'David Lee');
257+
```
258+
259+
我们希望删除 "store_details" 表中与 "sales" 表中无销售记录的店铺对应的行:
260+
261+
```sql
262+
WITH stores_with_sales AS (
263+
SELECT DISTINCT storeid
264+
FROM sales
265+
)
266+
DELETE FROM store_details
267+
WHERE storeid NOT IN (SELECT storeid FROM stores_with_sales);
268+
```
269+
270+
### 递归 CTE
271+
272+
首先,我们创建一个表来存储员工数据,包括他们的 ID、姓名和经理 ID。
273+
274+
```sql
275+
CREATE TABLE Employees (
276+
EmployeeID INT,
277+
EmployeeName VARCHAR(100),
278+
ManagerID INT
279+
);
280+
```
281+
282+
接下来,我们向表中插入示例数据,以表示一个简单的组织结构。
283+
284+
```sql
285+
INSERT INTO Employees (EmployeeID, EmployeeName, ManagerID) VALUES
286+
(1, 'Alice', NULL), -- Alice 是 CEO
287+
(2, 'Bob', 1), -- Bob 向 Alice 报告
288+
(3, 'Charlie', 1), -- Charlie 向 Alice 报告
289+
(4, 'David', 2), -- David 向 Bob 报告
290+
(5, 'Eve', 2), -- Eve 向 Bob 报告
291+
(6, 'Frank', 3); -- Frank 向 Charlie 报告
292+
```
293+
294+
现在,我们使用递归 CTE 来查找特定经理(例如 Alice,员工 ID = 1)下属的员工层级结构。
295+
296+
```sql
297+
WITH RECURSIVE EmployeeHierarchy AS (
298+
-- 初始查询:从指定的经理(Alice)开始
299+
SELECT EmployeeID, EmployeeName, ManagerID
300+
FROM Employees
301+
WHERE ManagerID IS NULL -- Alice,因为她没有经理
302+
UNION ALL
303+
-- 递归查询:查找当前级别的下属员工
304+
SELECT e.EmployeeID, e.EmployeeName, e.ManagerID
305+
FROM Employees e
306+
INNER JOIN EmployeeHierarchy eh ON e.ManagerID = eh.EmployeeID
307+
)
308+
SELECT * FROM EmployeeHierarchy;
309+
```
310+
311+
输出将列出 Alice 下属的所有员工:
312+
313+
```sql
314+
┌──────────────────────────────────────────────────────┐
315+
│ employeeid │ employeename │ managerid │
316+
├─────────────────┼──────────────────┼─────────────────┤
317+
1 │ Alice │ NULL
318+
2 │ Bob │ 1
319+
3 │ Charlie │ 1
320+
4 │ David │ 2
321+
5 │ Eve │ 2
322+
6 │ Frank │ 3
323+
└──────────────────────────────────────────────────────┘
324+
```
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
22
"label": "GROUP BY"
3-
}
3+
}

docs/cn/guides/54-query/01-groupby/group-by-cube.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
title: GROUP BY CUBE
33
---
44

5-
`GROUP BY CUBE`[GROUP BY](index.md) 子句的一个扩展,类似于 [GROUP BY ROLLUP](group-by-rollup.md)。除了生成 `GROUP BY ROLLUP` 的所有行之外,`GROUP BY CUBE` 还添加了所有的“交叉表”行。小计行是进一步聚合的行,其值是通过计算用于产生分组行的相同聚合函数得出的
5+
`GROUP BY CUBE`[GROUP BY](index.md) 子句的扩展,类似于 [GROUP BY ROLLUP](group-by-rollup.md)。除了生成 `GROUP BY ROLLUP` 的所有行之外,`GROUP BY CUBE` 还添加了所有“交叉表”行。子总计行是进一步聚合的行,其值是通过计算用于生成分组行的相同聚合函数得出的
66

7-
`CUBE` 分组相当于一系列分组集合,并且本质上是一个更短的规范。CUBE 规范的 N 个元素对应于 `2^N GROUPING SETS`
7+
`CUBE` 分组相当于一系列分组集,本质上是一种更简洁的规范。CUBE 规范的 N 个元素对应于 `2^N` 个分组集
88

99
## 语法
1010

@@ -22,11 +22,11 @@ GROUP BY CUBE ( groupCube [ , groupCube [ , ... ] ] )
2222
groupCube ::= { <column_alias> | <position> | <expr> }
2323
```
2424

25-
- `<column_alias>`查询块 SELECT 列表中出现的列别名
25+
- `<column_alias>`: 查询块 SELECT 列表中出现的列别名
2626

27-
- `<position>`SELECT 列表中表达式的位置
27+
- `<position>`: SELECT 列表中表达式的位置
2828

29-
- `<expr>`:当前作用域中表上的任何表达式
29+
- `<expr>`: 当前作用域内表上的任何表达式
3030

3131
## 示例
3232

docs/cn/guides/54-query/01-groupby/group-by-grouping-sets.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
title: GROUP BY GROUPING SETS
33
---
44

5-
`GROUP BY GROUPING SETS` [GROUP BY](index.md) 子句的一个强大扩展,它允许在单个语句中计算多个 group-by 子句。分组集是一组维度列。
5+
`GROUP BY GROUPING SETS` 是对 [GROUP BY](index.md) 子句的强大扩展,允许在一个语句中计算多个分组操作。分组集是一组维度列。
66

7-
`GROUP BY GROUPING SETS` 相当于同一结果集中两个或多个 GROUP BY 操作的 UNION:
7+
`GROUP BY GROUPING SETS` 等同于在同一结果集中对两个或多个 GROUP BY 操作进行 UNION:
88

9-
- `GROUP BY GROUPING SETS((a))` 相当于单个分组集操作 `GROUP BY a`
9+
- `GROUP BY GROUPING SETS((a))` 等同于单个分组集操作 `GROUP BY a`
1010

11-
- `GROUP BY GROUPING SETS((a),(b))` 相当于 `GROUP BY a UNION ALL GROUP BY b`
11+
- `GROUP BY GROUPING SETS((a),(b))` 等同于 `GROUP BY a UNION ALL GROUP BY b`
1212

1313
## 语法
1414

@@ -26,11 +26,11 @@ GROUP BY GROUPING SETS ( groupSet [ , groupSet [ , ... ] ] )
2626
groupSet ::= { <column_alias> | <position> | <expr> }
2727
```
2828

29-
- `<column_alias>`查询块 SELECT 列表中出现的列别名
29+
- `<column_alias>`: 查询块 SELECT 列表中出现的列别名
3030

31-
- `<position>`SELECT 列表中表达式的位置
31+
- `<position>`: SELECT 列表中表达式的位置
3232

33-
- `<expr>`:当前作用域中表中的任何表达式
33+
- `<expr>`: 当前作用域内表上的任何表达式
3434

3535
## 示例
3636

@@ -46,7 +46,7 @@ CREATE TABLE sales (
4646
quantity INT
4747
);
4848

49-
-- 将示例数据插入销售表
49+
-- 向销售表中插入示例数据
5050
INSERT INTO sales (id, sale_date, product_id, store_id, quantity)
5151
VALUES (1, '2021-01-01', 101, 1, 5),
5252
(2, '2021-01-01', 102, 1, 10),
@@ -66,7 +66,7 @@ FROM sales
6666
GROUP BY GROUPING SETS((pid), (sid));
6767
```
6868

69-
此查询等价于
69+
此查询等同于
7070

7171
```sql
7272
SELECT product_id AS pid,
@@ -106,7 +106,7 @@ FROM sales
106106
GROUP BY GROUPING SETS((1), (2));
107107
```
108108

109-
此查询等价于
109+
此查询等同于
110110

111111
```sql
112112
SELECT product_id,

0 commit comments

Comments
 (0)