Files
smart-data-dev-skill/one-skill/smart-data-developer/references/sql/reference/kudu-sql-syntax.md
2026-05-13 11:03:00 +08:00

337 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 INTOKudu 核心能力)
```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 TABLEKudu 特有)
```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 ...;
```