Add one-skill
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
# Kudu (via Impala) SQL 语法参考
|
||||
|
||||
> **重要**:Kudu 本身没有 SQL 引擎,通过 Impala 访问。本文档是 Impala SQL 操作 Kudu 表的语法参考。
|
||||
|
||||
## 数据类型
|
||||
|
||||
| 类型 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| BOOLEAN | 布尔 | active BOOLEAN |
|
||||
| TINYINT | 1字节整数 | level TINYINT |
|
||||
| SMALLINT | 2字节整数 | age SMALLINT |
|
||||
| INT | 4字节整数 | count INT |
|
||||
| BIGINT | 8字节整数 | id BIGINT |
|
||||
| FLOAT | 4字节浮点 | score FLOAT |
|
||||
| DOUBLE | 8字节浮点 | price DOUBLE |
|
||||
| DECIMAL(p,s) | 定点数 | amount DECIMAL(18,2) |
|
||||
| STRING | 变长字符串 | name STRING |
|
||||
| VARCHAR(n) | 变长字符串(限长) | code VARCHAR(50) |
|
||||
| CHAR(n) | 定长字符串 | flag CHAR(1) |
|
||||
| TIMESTAMP | 时间戳(微秒精度) | created_at TIMESTAMP |
|
||||
| DATE | 日期 | birth_date DATE |
|
||||
| BINARY | 二进制 | data BINARY |
|
||||
|
||||
**注意**:Kudu 不支持 ARRAY、MAP、STRUCT 等复杂类型。
|
||||
|
||||
---
|
||||
|
||||
## 时间函数
|
||||
|
||||
```sql
|
||||
-- 当前时间
|
||||
NOW() -- 当前日期时间
|
||||
CURRENT_TIMESTAMP() -- 当前时间戳
|
||||
UNIX_TIMESTAMP() -- 当前 Unix 时间戳(秒)
|
||||
TO_DATE(NOW()) -- 当前日期
|
||||
|
||||
-- 格式转换
|
||||
FROM_UNIXTIME(timestamp, 'yyyy-MM-dd') -- Unix 时间戳转格式化字符串
|
||||
FROM_UNIXTIME(timestamp, 'yyyy-MM-dd HH:mm:ss')
|
||||
CAST(string_col AS TIMESTAMP) -- 字符串转时间戳
|
||||
CAST(timestamp_col AS STRING) -- 时间戳转字符串
|
||||
|
||||
-- 日期计算
|
||||
DAYS_ADD(date_col, 7) -- 加7天
|
||||
DAYS_SUB(date_col, 7) -- 减7天
|
||||
ADD_MONTHS(date_col, 3) -- 加3个月(Impala 6.0+)
|
||||
DATE_ADD(date_col, INTERVAL 7 DAY) -- 加7天(标准语法)
|
||||
DATEDIFF(end_date, start_date) -- 日期差(天数)
|
||||
MONTHS_BETWEEN(date1, date2) -- 月份差
|
||||
|
||||
-- 日期提取
|
||||
YEAR(date_col) -- 年
|
||||
MONTH(date_col) -- 月
|
||||
DAY(date_col) -- 日
|
||||
DAYOFWEEK(date_col) -- 周几 (1=周日)
|
||||
DAYOFYEAR(date_col) -- 年中第几天
|
||||
HOUR(timestamp_col) -- 时
|
||||
MINUTE(timestamp_col) -- 分
|
||||
SECOND(timestamp_col) -- 秒
|
||||
QUARTER(date_col) -- 季度 (1-4)
|
||||
WEEKOFYEAR(date_col) -- 年中第几周
|
||||
|
||||
-- Impala 日期格式符
|
||||
-- yyyy: 4位年, MM: 2位月, dd: 2位日
|
||||
-- HH: 24小时制, mm: 分钟, ss: 秒
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 字符串函数
|
||||
|
||||
```sql
|
||||
-- 常用函数
|
||||
CONCAT(str1, str2) -- 字符串拼接(仅2个参数)
|
||||
CONCAT_WS('-', str1, str2, ...) -- 用分隔符拼接
|
||||
LOWER(str) -- 转小写
|
||||
UPPER(str) -- 转大写
|
||||
TRIM(str) -- 去两端空格
|
||||
LTRIM(str) -- 去左空格
|
||||
RTRIM(str) -- 去右空格
|
||||
LENGTH(str) -- 字符串长度
|
||||
SUBSTR(str, pos, len) -- 截取字符串(pos从1开始)
|
||||
SUBSTRING(str, pos, len) -- 同上
|
||||
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) -- 正则提取
|
||||
REGEXP_REPLACE(str, pattern, replacement) -- 正则替换
|
||||
|
||||
-- 分割
|
||||
SPLIT_PART(str, delimiter, idx) -- 取分割后第idx部分
|
||||
|
||||
-- 其他
|
||||
INITCAP(str) -- 首字母大写
|
||||
LPAD(str, len, pad) -- 左填充
|
||||
RPAD(str, len, pad) -- 右填充
|
||||
HEX(col) -- 转16进制
|
||||
UNHEX(str) -- 16进制转字符串
|
||||
```
|
||||
|
||||
**注意**:Impala 的 `CONCAT` 只接受 2 个参数,多参数拼接用 `CONCAT_WS`。
|
||||
|
||||
---
|
||||
|
||||
## 聚合函数
|
||||
|
||||
```sql
|
||||
-- 基础聚合
|
||||
COUNT(*) -- 计数(含NULL行)
|
||||
COUNT(col) -- 计数(不含NULL)
|
||||
COUNT(DISTINCT col) -- 去重计数
|
||||
SUM(col) -- 求和
|
||||
AVG(col) -- 平均值
|
||||
MIN(col) -- 最小值
|
||||
MAX(col) -- 最大值
|
||||
|
||||
-- 集合聚合
|
||||
GROUP_CONCAT(col SEPARATOR ',') -- 字符串聚合
|
||||
|
||||
-- 统计函数
|
||||
VARIANCE(col) -- 方差
|
||||
VAR_POP(col) -- 总体方差
|
||||
VAR_SAMP(col) -- 样本方差
|
||||
STDDEV(col) -- 标准差
|
||||
STDDEV_POP(col) -- 总体标准差
|
||||
STDDEV_SAMP(col) -- 样本标准差
|
||||
|
||||
-- 近似函数
|
||||
NDV(col) -- 近似去重计数(Impala 特有,比 COUNT(DISTINCT) 快)
|
||||
APPROX_COUNT_DISTINCT(col) -- 近似去重计数
|
||||
|
||||
-- 其他
|
||||
FIRST_VALUE(col) -- 窗口内第一个值
|
||||
LAST_VALUE(col) -- 窗口内最后一个值
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 条件表达式
|
||||
|
||||
```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)
|
||||
|
||||
-- ISNULL / ISNOTNULL
|
||||
ISNULL(col) -- 判断是否为NULL
|
||||
ISNOTNULL(col) -- 判断是否不为NULL
|
||||
|
||||
-- NVL(空值替换)
|
||||
NVL(col, default_value)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kudu 特有操作
|
||||
|
||||
### INSERT INTO
|
||||
|
||||
```sql
|
||||
-- 追加写入
|
||||
INSERT INTO kudu_table VALUES (1, 'test', 100.00);
|
||||
INSERT INTO kudu_table SELECT * FROM other_table WHERE ...;
|
||||
```
|
||||
|
||||
### UPSERT INTO(Kudu 核心能力)
|
||||
|
||||
```sql
|
||||
-- 主键存在则更新,不存在则插入
|
||||
UPSERT INTO kudu_table VALUES (1, 'test', 100.00);
|
||||
UPSERT INTO kudu_table SELECT * FROM staging_table WHERE ...;
|
||||
```
|
||||
|
||||
### UPDATE
|
||||
|
||||
```sql
|
||||
-- 更新数据(主键列不可更新)
|
||||
UPDATE kudu_table SET status = 'active' WHERE id = 1;
|
||||
UPDATE kudu_table SET amount = amount * 1.1 WHERE date < '2026-01-01';
|
||||
```
|
||||
|
||||
### DELETE
|
||||
|
||||
```sql
|
||||
-- 删除数据
|
||||
DELETE FROM kudu_table WHERE id = 1;
|
||||
DELETE FROM kudu_table WHERE date < '2026-01-01';
|
||||
```
|
||||
|
||||
### ALTER TABLE(Kudu 特有)
|
||||
|
||||
```sql
|
||||
-- 添加列
|
||||
ALTER TABLE kudu_table ADD COLUMNS (new_col STRING COMMENT '新列');
|
||||
|
||||
-- 删除列
|
||||
ALTER TABLE kudu_table DROP COLUMN old_col;
|
||||
|
||||
-- 修改列类型
|
||||
ALTER TABLE kudu_table CHANGE old_name new_name STRING;
|
||||
|
||||
-- 添加范围分区
|
||||
ALTER TABLE kudu_table ADD RANGE PARTITION
|
||||
'2026-06-01' <= VALUES < '2026-07-01';
|
||||
|
||||
-- 删除范围分区
|
||||
ALTER TABLE kudu_table DROP RANGE PARTITION
|
||||
'2026-01-01' <= VALUES < '2026-02-01';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 分区操作
|
||||
|
||||
```sql
|
||||
-- Hash 分区(建表时指定)
|
||||
PARTITION BY HASH(id) PARTITIONS 8
|
||||
|
||||
-- Range 分区(建表时指定)
|
||||
PARTITION BY RANGE(stat_date) (
|
||||
PARTITION '2026-01-01' <= VALUES < '2026-02-01',
|
||||
PARTITION '2026-02-01' <= VALUES < '2026-03-01'
|
||||
)
|
||||
|
||||
-- Hash + Range 组合
|
||||
PARTITION BY
|
||||
HASH(id) PARTITIONS 4,
|
||||
RANGE(stat_date) (...)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与 Spark SQL / Hive 的主要差异
|
||||
|
||||
| 特性 | Spark SQL | Hive | Kudu (Impala) | 说明 |
|
||||
|------|-----------|------|--------------|------|
|
||||
| **INSERT OVERWRITE** | ✅ | ✅ | ❌ | Kudu 不支持,用 DELETE + INSERT 替代 |
|
||||
| **UPSERT** | ❌ | ❌ | ✅ | Kudu 独有核心能力 |
|
||||
| **UPDATE** | ❌ | 仅ACID表 | ✅ | Kudu 原生支持 |
|
||||
| **DELETE** | ❌ | 仅ACID表 | ✅ | Kudu 原生支持 |
|
||||
| **主键约束** | ❌ 无约束 | ❌ 无约束 | ✅ 强制主键 | Kudu 表必须有主键 |
|
||||
| **复杂类型** | ✅ ARRAY/MAP/STRUCT | ✅ 完整支持 | ❌ 不支持 | Kudu 限制 |
|
||||
| **CONCAT 多参数** | ✅ 任意个数 | ✅ 任意个数 | ❌ 仅2个参数 | Impala 用 CONCAT_WS |
|
||||
| **近似去重** | `approx_count_distinct` | `approx_count_distinct` | `NDV` | Impala 特有函数名 |
|
||||
| **临时表链式处理** | ✅ 推荐 | ✅ 推荐 | ❌ 不需要 | Kudu 用 UPSERT 单步 |
|
||||
| **CTE (WITH)** | ✅ 支持 | ✅ 支持 | ✅ 支持 | 都支持 |
|
||||
| **MERGE INTO** | ✅ 支持 | ❌ | ❌ | 用 UPSERT 替代 |
|
||||
| **分区类型** | 目录分区 | 目录分区 | Hash/Range 内置 | Kudu 分区机制不同 |
|
||||
| **分桶** | 可选 | 可选 | Hash 分区替代 | 概念类似但实现不同 |
|
||||
| **日期格式** | `yyyy-MM-dd` | `yyyy-MM-dd` | `yyyy-MM-dd` | 格式一致 |
|
||||
| **collect_list/set** | ✅ | ✅ | ❌ | Impala 用 GROUP_CONCAT |
|
||||
| **ALTER ADD COLUMN** | ✅ | ✅ | ✅ | Kudu 支持在线加列 |
|
||||
| **ALTER DROP COLUMN** | 部分支持 | ✅ | ✅ | Kudu 支持在线删列 |
|
||||
|
||||
---
|
||||
|
||||
## 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_{业务简称}_{步骤序号}`
|
||||
|
||||
### Kudu 特有规则
|
||||
|
||||
1. **Kudu 表不支持 `INSERT OVERWRITE`**,用 `DELETE + INSERT` 或 `UPSERT` 替代
|
||||
2. **最后一步优先使用 `UPSERT INTO`**(Kudu 核心优势:主键存在则更新,不存在则插入)
|
||||
3. 需要全量刷新时:先 `DELETE FROM` 再 `INSERT INTO`
|
||||
4. 支持 `UPDATE` 和 `DELETE`(Kudu 表独有)
|
||||
5. Kudu 表必须有 `PRIMARY KEY`,主键列不能为 NULL
|
||||
6. `CONCAT` 只接受 2 个参数,多参数用 `CONCAT_WS`
|
||||
7. 不支持 `collect_list` / `collect_set`,用 `GROUP_CONCAT` 替代
|
||||
8. 近似去重用 `NDV()` 函数
|
||||
9. 时间范围筛选:
|
||||
```sql
|
||||
-- 日账期过滤
|
||||
WHERE stat_date = '${day_id}'
|
||||
-- 日期范围
|
||||
WHERE stat_date >= DAYS_SUB(TO_DATE('${day_id}'), 30)
|
||||
AND stat_date < '${day_id}'
|
||||
```
|
||||
|
||||
### SQL 脚本结构
|
||||
|
||||
```sql
|
||||
-- =====================================================================
|
||||
-- @SqlName: kudu-D-SQL-{表名}
|
||||
-- @Engine: kudu
|
||||
-- ...(头注释)
|
||||
-- =====================================================================
|
||||
|
||||
-- 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 ...;
|
||||
|
||||
-- 最后一步:UPSERT 写入 Kudu 目标表
|
||||
UPSERT INTO ${db_eda_env}.target_table
|
||||
SELECT ...;
|
||||
```
|
||||
Reference in New Issue
Block a user