Add one-skill

This commit is contained in:
Xin Wang
2026-05-13 11:03:00 +08:00
parent a4c8b29176
commit f9e36ef92d
34 changed files with 7656 additions and 0 deletions

View File

@@ -0,0 +1,320 @@
# Apache Doris SQL 语法参考
## 数据类型
| 类型 | 说明 | 示例 |
|------|------|------|
| BOOLEAN | 布尔 | active BOOLEAN |
| TINYINT | 1字节整数 | level TINYINT |
| SMALLINT | 2字节整数 | age SMALLINT |
| INT | 4字节整数 | count INT |
| BIGINT | 8字节整数 | id BIGINT |
| LARGEINT | 16字节整数 | hash_key LARGEINT |
| FLOAT | 4字节浮点 | score FLOAT |
| DOUBLE | 8字节浮点 | price DOUBLE |
| DECIMAL(p,s) | 定点数 | amount DECIMAL(18,2) |
| DATE | 日期 | birth_date DATE |
| DATETIME | 日期时间(精确到秒) | created_at DATETIME |
| CHAR(n) | 定长字符串 | code CHAR(10) |
| VARCHAR(n) | 变长字符串 | name VARCHAR(100) |
| STRING | 变长字符串(无长度限制) | description STRING |
| BITMAP | 位图(精确去重) | user_bitmap BITMAP |
| HLL | HyperLogLog近似去重 | user_hll HLL |
| JSON | JSON 数据 | props JSON |
| ARRAY\<type\> | 数组 | tags ARRAY\<STRING\> |
| MAP\<k,v\> | 映射 | props MAP\<STRING,STRING\> |
| STRUCT\<field:type,...\> | 结构体 | info STRUCT\<id:INT,name:STRING\> |
---
## 时间函数
```sql
-- 当前时间
NOW() -- 当前日期时间
CURDATE() -- 当前日期
CURRENT_TIMESTAMP() -- 当前时间戳
-- 格式转换
DATE_FORMAT(date_col, '%Y-%m-%d') -- 日期格式化
DATE_FORMAT(datetime_col, '%Y-%m-%d %H:%i:%s') -- 时间格式化
STR_TO_DATE(str, '%Y-%m-%d') -- 字符串转日期
-- 日期计算
DATE_ADD(date_col, INTERVAL 7 DAY) -- 加7天
DATE_SUB(date_col, INTERVAL 7 DAY) -- 减7天
DATEDIFF(end_date, start_date) -- 日期差(天数)
TIMESTAMPDIFF(unit, start, end) -- 时间差(指定单位)
TIMESTAMPADD(unit, interval, datetime) -- 时间加
-- 日期提取
YEAR(date_col) -- 年
MONTH(date_col) -- 月
DAY(date_col) -- 日
HOUR(datetime_col) -- 时
MINUTE(datetime_col) -- 分
SECOND(datetime_col) -- 秒
QUARTER(date_col) -- 季度 (1-4)
WEEK(date_col) -- 年中第几周
DAYOFWEEK(date_col) -- 周几 (1=周日)
DAYOFYEAR(date_col) -- 年中第几天
-- Unix 时间戳
UNIX_TIMESTAMP() -- 当前 Unix 时间戳
UNIX_TIMESTAMP(datetime_col) -- 转换为 Unix 时间戳
FROM_UNIXTIME(timestamp) -- Unix 时间戳转时间字符串
FROM_UNIXTIME(timestamp, fmt) -- 带格式的转换
-- Doris 日期格式符(不同于 Spark
-- %Y: 4位年, %m: 2位月, %d: 2位日
-- %H: 24小时制, %i: 分钟, %s: 秒
-- %j: 年中天数, %W: 周名
```
---
## 字符串函数
```sql
-- 常用函数
CONCAT(str1, str2, ...) -- 字符串拼接
CONCAT_WS('-', str1, str2, ...) -- 用分隔符拼接
LOWER(str) -- 转小写
UPPER(str) -- 转大写
TRIM(str) -- 去两端空格
LTRIM(str) -- 去左空格
RTRIM(str) -- 去右空格
LENGTH(str) -- 字符串长度
CHAR_LENGTH(str) -- 字符数(中文友好)
SUBSTRING(str, pos, len) -- 截取字符串pos从1开始
LEFT(str, len) -- 取左边len个字符
RIGHT(str, len) -- 取右边len个字符
REVERSE(str) -- 反转字符串
REPEAT(str, n) -- 重复n次
SPACE(n) -- 生成n个空格
-- 查找与替换
INSTR(str, substr) -- 查找子串位置
LOCATE(substr, str, pos) -- 从pos位置查找
REPLACE(str, old, new) -- 替换
REGEXP_EXTRACT(str, pattern, idx) -- 正则提取(注意和 Spark 参数不同)
REGEXP_REPLACE(str, pattern, replacement) -- 正则替换
-- 分割
SPLIT_BY_STRING(str, delimiter) -- 分割Doris 特有)
SPLIT_PART(str, delimiter, idx) -- 取分割后的第idx部分
-- 其他
INITCAP(str) -- 首字母大写
LPAD(str, len, pad) -- 左填充
RPAD(str, len, pad) -- 右填充
HEX(str) -- 转16进制
UNHEX(str) -- 16进制转字符串
```
---
## 聚合函数
```sql
-- 基础聚合
COUNT(*) -- 计数含NULL行
COUNT(col) -- 计数不含NULL
COUNT(DISTINCT col) -- 去重计数
SUM(col) -- 求和
AVG(col) -- 平均值
MIN(col) -- 最小值
MAX(col) -- 最大值
-- 集合聚合
GROUP_CONCAT(col SEPARATOR ',') -- 字符串聚合(类似 collect_list
APPROX_COUNT_DISTINCT(col) -- 近似去重计数
-- 统计函数
VARIANCE(col) -- 方差
VAR_POP(col) -- 总体方差
VAR_SAMP(col) -- 样本方差
STDDEV(col) -- 标准差
STDDEV_POP(col) -- 总体标准差
STDDEV_SAMP(col) -- 样本标准差
-- Bitmap 精确去重Doris 特有)
-- 用于 Aggregate Key 模型中定义为 BITMAP 的列
-- bitmap_union_count(bitmap_col) -- 精确去重计数
-- bitmap_union(bitmap_col) -- 合并 bitmap
-- bitmap_hash(col) -- 将值转为 bitmap用于写入
-- HLL 近似去重Doris 特有)
-- hll_union_agg(hll_col) -- 近似去重计数
-- hll_cardinality(hll_col) -- 返回 HLL 基数
-- hll_hash(col) -- 将值转为 HLL用于写入
```
---
## 条件表达式
```sql
-- CASE WHEN
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE default_result
END
-- CASE 字段匹配
CASE field
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE default_result
END
-- COALESCE取第一个非空值
COALESCE(col1, col2, default_value)
-- NULLIF相等返回NULL
NULLIF(col1, col2)
-- IF简单条件
IF(condition, true_value, false_value)
-- IFNULL空值替换等同 NVL
IFNULL(col, default_value)
```
---
## JSON 函数
```sql
-- 解析与提取
JSON_PARSE(json_str) -- 解析 JSON 字符串
JSON_EXTRACT(json_str, '$.field') -- 提取 JSON 字段(返回 JSON 类型)
JSON_EXTRACT_STRING(json_str, '$.field') -- 提取 JSON 字段(返回 STRING
JSON_EXTRACT_INT(json_str, '$.field') -- 提取 JSON 字段(返回 INT
JSON_EXTRACT_DOUBLE(json_str, '$.field') -- 提取 JSON 字段(返回 DOUBLE
JSON_EXTRACT_BOOL(json_str, '$.field') -- 提取 JSON 字段(返回 BOOLEAN
-- 路径语法
-- $ : 根节点
-- $.field : 对象字段
-- $[0] : 数组索引
-- $.a.b : 嵌套字段
-- 构造
JSON_OBJECT('key1', val1, 'key2', val2) -- 构造 JSON 对象
JSON_ARRAY(val1, val2, ...) -- 构造 JSON 数组
-- 查询
JSON_LENGTH(json_str) -- JSON 长度
JSON_KEYS(json_str) -- JSON 所有 key
JSON_VALID(json_str) -- 是否合法 JSON
```
---
## ARRAY 函数
```sql
-- 创建
ARRAY(val1, val2, ...) -- 创建数组
-- 访问
array_contains(arr, val) -- 判断是否包含
element_at(arr, idx) -- 取元素idx从1开始
arr[idx] -- 取元素idx从0开始
-- 操作
SIZE(arr) -- 数组长度
ARRAY_JOIN(arr, delimiter) -- 数组转字符串
CONCAT(arr1, arr2) -- 数组拼接
-- 展开与排序
EXPLODE(arr) -- 展开数组为多行LATERAL VIEW 中使用)
ARRAY_SORT(arr) -- 排序
ARRAY_DISTINCT(arr) -- 去重
```
---
## 与 Spark SQL 的主要差异
| 特性 | Spark SQL | Apache Doris | 说明 |
|------|-----------|-------------|------|
| **日期格式符** | `yyyy-MM-dd` | `%Y-%m-%d` | Doris 用 MySQL 风格格式符 |
| **当前时间** | `current_timestamp()` | `NOW()``CURRENT_TIMESTAMP()` | 都支持Doris 偏好 NOW() |
| **日期加减** | `date_add(col, 7)` | `DATE_ADD(col, INTERVAL 7 DAY)` | Doris 需要 INTERVAL 语法 |
| **正则提取** | `regexp_extract(str, pattern, idx)` | `REGEXP_EXTRACT(str, pattern, idx)` | 参数名可能不同 |
| **LEFT SEMI JOIN** | ✅ 支持 | ❌ 不支持 | 用 IN 子查询替代 |
| **LEFT ANTI JOIN** | ✅ 支持 | ❌ 不支持 | 用 NOT IN / NOT EXISTS 替代 |
| **INSERT OVERWRITE** | ✅ 支持 | ✅ 2.0+ 支持 | 早期版本不支持 |
| **CTE (WITH)** | ✅ 支持 | ✅ 支持 | 都支持 |
| **MERGE INTO** | ✅ 支持 | ❌ 不支持 | Doris 用 UPSERT 替代 |
| **临时表链式处理** | ✅ 推荐 | ✅ 统一规范 | 编码规范层面统一禁止 CTE |
| **精确去重** | COUNT(DISTINCT) | COUNT(DISTINCT) 或 BITMAP | Doris BITMAP 性能更好 |
| **近似去重** | `approx_count_distinct` | HLL 类型 | Doris 内置 HLL 类型 |
| **UPDATE/DELETE** | ❌ 不支持 | ✅ 支持 | Doris 支持 DML |
| **UPSERT** | ❌ 不支持 | ❌ 不直接支持 | 用 Aggregate/Unique Key 模型替代 |
| **分页** | LIMIT无OFFSET | LIMIT + OFFSET | Doris 完整支持 |
| **JSON** | `get_json_object` | `JSON_EXTRACT_STRING` 等系列函数 | 函数名完全不同 |
| **collect_list/set** | ✅ 支持 | ❌ 不直接支持 | 用 GROUP_CONCAT 替代 |
| **LATERAL VIEW explode** | ✅ 支持 | ✅ 支持 | 语法兼容 |
---
## SQL 生成规则
### 通用规则(所有引擎统一)
1. **禁止使用 CTE (WITH 子句)**,每个主要逻辑步骤必须物化为临时表
2. **先 DROP 再 CREATE**`DROP TABLE IF EXISTS ...; CREATE TABLE ... AS SELECT ...;`
3. **禁止 `SELECT *`**,必须明确列出所有字段
4. 多表查询时所有表必须使用简短别名
5. 每个步骤前添加注释说明
6. **谓词下推**过滤条件前置JOIN 时在 WHERE 中一并添加过滤
7. 临时表命名:`${db_tmp_env}.tmp_{业务简称}_{步骤序号}`
### Doris 特有规则
1. 使用 `INSERT INTO` 写入目标表Doris 2.0+ 也支持 `INSERT OVERWRITE`
2. Aggregate Key 表自动合并相同 Key 的数据
3. Unique Key 表自动按主键去重,保留最新数据
4. 不支持 `LEFT SEMI JOIN` / `LEFT ANTI JOIN`,用 `IN` / `NOT IN` 替代
5. 精确去重推荐 `BITMAP`,近似去重推荐 `HLL`
6. 日期函数用 MySQL 风格:
- `DATE_FORMAT(col, '%Y-%m-%d')`(不是 `yyyy-MM-dd`
- `DATE_ADD(col, INTERVAL 7 DAY)`(不是 `date_add(col, 7)`
- `CURDATE()` / `NOW()`
7. 不支持 `collect_list` / `collect_set`,用 `GROUP_CONCAT` 替代
8. 时间范围筛选:
```sql
-- 日账期过滤
WHERE stat_date = '${day_id}'
-- 最近N个月
WHERE stat_date >= DATE_FORMAT(DATE_SUB(STR_TO_DATE('${month_id}', '%Y%m'), INTERVAL N MONTH), '%Y%m')
AND stat_date < '${month_id}'
```
### SQL 脚本结构
```sql
-- =====================================================================
-- @SqlName: doris-D-SQL-{表名}
-- @Engine: doris
-- ...(头注释)
-- =====================================================================
-- Step01: {步骤描述}
DROP TABLE IF EXISTS ${db_tmp_env}.tmp_xxx_01;
CREATE TABLE ${db_tmp_env}.tmp_xxx_01 AS
SELECT ...;
-- Step02: {步骤描述}
DROP TABLE IF EXISTS ${db_tmp_env}.tmp_xxx_02;
CREATE TABLE ${db_tmp_env}.tmp_xxx_02 AS
SELECT ...;
-- 最后一步:写入目标表
INSERT INTO ${db_eda_env}.target_table
SELECT ...;
```