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

11 KiB
Raw Blame History

Hive SQL 语法参考

数据类型

类型 说明 示例
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)
BOOLEAN 布尔 active BOOLEAN
STRING 变长字符串 name STRING
VARCHAR(n) 变长字符串(限长) code VARCHAR(50)
CHAR(n) 定长字符串 flag CHAR(1)
DATE 日期 birth_date DATE
TIMESTAMP 时间戳(纳秒精度) created_at TIMESTAMP
BINARY 二进制 data BINARY
ARRAY<type> 数组 tags ARRAY<STRING>
MAP<k,v> 映射 props MAP<STRING,STRING>
STRUCT<f1:t1,...> 结构体 user STRUCT<id:INT,name:STRING>
UNIONTYPE<t1,t2,...> 联合类型 value UNIONTYPE<INT,STRING>

时间函数

-- 当前时间
current_date()                  -- 当前日期
current_timestamp()             -- 当前时间戳
unix_timestamp()                -- 当前 Unix 时间戳(秒)

-- 格式转换
date_format(date_col, 'yyyy-MM-dd')          -- 日期格式化
date_format(timestamp_col, 'yyyy-MM-dd HH:mm:ss')  -- 时间格式化
to_date(string_col)                           -- 字符串转日期
to_date(string_col, 'yyyy-MM-dd')            -- 字符串转日期(带格式)
from_unixtime(timestamp)                      -- Unix 时间戳转字符串
from_unixtime(timestamp, 'yyyy-MM-dd')        -- 带格式转换

-- 日期计算
date_add(date_col, 7)           -- 加7天
date_sub(date_col, 7)           -- 减7天
add_months(date_col, 3)         -- 加3个月
datediff(end_date, start_date)  -- 日期差(天数)
months_between(date1, date2)    -- 月份差

-- 日期提取
year(date_col)                  -- 年
month(date_col)                 -- 月
day(date_col)                   -- 日
dayofmonth(date_col)            -- 月中第几天
dayofweek(date_col)             -- 周几 (1=周日, 7=周六)
hour(timestamp_col)             -- 时
minute(timestamp_col)           -- 分
second(timestamp_col)           -- 秒
quarter(date_col)               -- 季度 (1-4)
weekofyear(date_col)            -- 年中第几周
last_day(date_col)              -- 月末日期
trunc(date_col, 'MM')           -- 月初日期
trunc(date_col, 'YY')           -- 年初日期

-- Unix 时间戳
unix_timestamp(date_col)        -- 转 Unix 时间戳
unix_timestamp(string_col, 'yyyy-MM-dd')  -- 指定格式转换
from_unixtime(timestamp)        -- Unix 时间戳转字符串

字符串函数

-- 常用函数
concat(str1, str2, ...)                     -- 字符串拼接
concat_ws('-', str1, str2, ...)             -- 用分隔符拼接
lower(str)                                  -- 转小写
upper(str)                                  -- 转大写
trim(str)                                   -- 去两端空格
ltrim(str)                                  -- 去左空格
rtrim(str)                                  -- 去右空格
length(str)                                 -- 字符串长度
substring(str, pos, len)                    -- 截取字符串pos从1开始
substr(str, pos, len)                       -- 同 substring
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(str, delimiter)                       -- 分割成数组

-- 其他
initcap(str)                                -- 首字母大写
lpad(str, len, pad)                         -- 左填充
rpad(str, len, pad)                         -- 右填充
hex(col)                                    -- 转16进制
unhex(str)                                  -- 16进制转字符串

聚合函数

-- 基础聚合
COUNT(*)                        -- 计数含NULL行
COUNT(col)                      -- 计数不含NULL
COUNT(DISTINCT col)             -- 去重计数
SUM(col)                        -- 求和
AVG(col)                        -- 平均值
MIN(col)                        -- 最小值
MAX(col)                        -- 最大值

-- 集合聚合
collect_list(col)               -- 返回数组(不去重)
collect_set(col)                -- 返回数组(去重)

-- 统计函数
variance(col)                   -- 方差
var_pop(col)                    -- 总体方差
var_samp(col)                   -- 样本方差
stddev(col)                     -- 标准差
stddev_pop(col)                 -- 总体标准差
stddev_samp(col)                -- 样本标准差

-- 近似函数
approx_count_distinct(col)      -- 近似去重计数(大数据量优化)

-- 其他
first(col)                      -- 第一个值
last(col)                       -- 最后一个值

条件表达式

-- 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)

-- NVL空值替换
NVL(col, default_value)

复杂类型操作

-- ARRAY 操作
array(val1, val2, ...)           -- 创建数组
array_contains(arr, val)         -- 判断是否包含
element_at(arr, idx)             -- 取元素idx从1开始
arr[idx]                         -- 取元素idx从0开始
size(arr)                        -- 数组长度
array_join(arr, delimiter)       -- 数组转字符串
sort_array(arr)                  -- 排序
array_distinct(arr)              -- 去重

-- 展开LATERAL VIEW + explode
-- 展开数组
SELECT id, tag
FROM table
LATERAL VIEW explode(tags) t AS tag;

-- 展开数组带索引
SELECT id, pos, tag
FROM table
LATERAL VIEW posexplode(tags) t AS pos, tag;

-- 展开 Map
SELECT id, map_key, map_value
FROM table
LATERAL VIEW explode(props) m AS map_key, map_value;

-- MAP 操作
map(key1, val1, key2, val2)      -- 创建 Map
str_to_map(str, delim1, delim2)  -- 字符串转 Map
map_contains(map, key)           -- 判断是否包含key
map_keys(map)                    -- 所有 key返回数组
map_values(map)                  -- 所有 value返回数组
size(map)                        -- Map大小

-- STRUCT 操作
named_struct('name1', val1, 'name2', val2)  -- 创建结构体
struct_col.field_name            -- 访问结构体字段

分区表操作

-- 创建分区表
CREATE TABLE target_table (
    id BIGINT,
    name STRING,
    amount DECIMAL(18,2)
)
PARTITIONED BY (day_id STRING)
STORED AS ORC;

-- 静态分区写入
INSERT OVERWRITE TABLE target_table
PARTITION (day_id = '${day_id}')
SELECT id, name, amount FROM source_table;

-- 动态分区写入
SET hive.exec.dynamic.partition = true;
SET hive.exec.dynamic.partition.mode = nonstrict;

INSERT OVERWRITE TABLE target_table
PARTITION (day_id)
SELECT id, name, amount, day_id FROM source_table;

-- 分区管理
SHOW PARTITIONS target_table;
ALTER TABLE target_table ADD IF NOT EXISTS PARTITION (day_id = '2026-05-10');
ALTER TABLE target_table DROP IF EXISTS PARTITION (day_id = '2026-01-01');

-- MSCK REPAIR恢复分区元数据
MSCK REPAIR TABLE target_table;

与 Spark SQL 的主要差异

特性 Spark SQL Hive 说明
LEFT SEMI JOIN 独立语法 支持(语义相同) Hive 也可用 IN 子查询替代
LEFT ANTI JOIN 独立语法 支持(语义相同) Hive 也可用 NOT IN 替代
CTE (WITH) 支持 Hive 0.13+ 支持 都支持但 Hive 中推荐物化临时表
INSERT OVERWRITE 支持 支持 写法一致
MERGE INTO 支持 不支持 Hive 不支持
UPDATE/DELETE 不支持 仅 ACID 表支持 普通 Hive 表不支持
collect_list/set 支持 支持 完全一致
LATERAL VIEW 支持 支持Hive 原生) Hive 首创的语法
分桶 JOIN 可优化 可优化SMB JOIN Hive 分桶优化更成熟
日期格式 yyyy-MM-dd yyyy-MM-dd 格式一致
临时表 CREATE TEMP TABLE CREATE TEMPORARY TABLE 关键字略有不同
存储格式 PARQUET/ORC ORC/PARQUET/TEXTFILE Hive 支持 TEXTFILE
分区发现 自动 需 MSCK REPAIR 或 ALTER Hive 需手动恢复
复杂类型 完整支持 完整支持 基本一致
窗口函数 完整支持 完整支持 语法一致

SQL 生成规则

通用规则(所有引擎统一)

  1. 禁止使用 CTE (WITH 子句),每个主要逻辑步骤必须物化为临时表
  2. 先 DROP 再 CREATEDROP TABLE IF EXISTS ...; CREATE TABLE ... AS SELECT ...;
  3. 禁止 SELECT *,必须明确列出所有字段
  4. 多表查询时所有表必须使用简短别名
  5. 每个步骤前添加注释说明
  6. 谓词下推过滤条件前置JOIN 时在 WHERE 中一并添加过滤
  7. 临时表命名:${db_tmp_env}.tmp_{业务简称}_{步骤序号}

Hive 特有规则

  1. 使用 INSERT OVERWRITE TABLE ... PARTITION (...) 写入目标表
  2. 动态分区需先 SET hive.exec.dynamic.partition = true;
  3. 分区列不能出现在表定义的列中Hive 特有约束)
  4. 支持 collect_list / collect_set 聚合
  5. 支持 LATERAL VIEW explode() 展开数组
  6. 日期函数:date_format(), to_date(), date_add(), add_months()(和 Spark 一致)
  7. 时间范围筛选:
    -- 日账期过滤
    WHERE day_id = '${day_id}'
    -- 最近N个月月份格式 yyyyMM
    WHERE month_id >= date_format(add_months(to_date('${month_id}', 'yyyyMM'), -N), 'yyyyMM')
      AND month_id < '${month_id}'
    

SQL 脚本结构

-- =====================================================================
-- @SqlName:         hive-D-SQL-{表名}
-- @Engine:          hive
-- ...(头注释)
-- =====================================================================

-- 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 OVERWRITE TABLE ${db_eda_env}.target_table
PARTITION (day_id = '${day_id}')
SELECT ...;