未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用范围与待维护事项
本文用于已有SQL基础的Impala类型与函数组合练习,不是已验证的全量函数清单。原稿未注明Impala版本或提供函数兼容性依据;递归CTE不适用于Impala,ARRAY/MAP构造、复杂类型写入与访问示例不能直接视为可执行代码,DATE_FORMAT、FORMAT_NUMBER等调用也需逐项核对。sales_records的建表和数据未在本篇提供,相关挑战须先准备依赖表。中文字符串处理需验证UTF-8行为,工作日、效率和客户分级仅为简化教学规则,不宜直接用于生产决策。
数据类型与函数 - Impala数据处理的核心工具
abstract 📋 本节概览
- 🎯 学习目标:了解Impala常见数据类型,练习常用内置函数,并识别需要按版本核对的示例
- 📚 前置知识:Impala SQL语法
- ⏱️ 预计用时:35分钟
🤔 为什么数据类型和函数很重要?
tip 💝 给数据处理新手的温暖指导
🤗 学习数据类型和函数就像学会使用专业工具箱!
如果你现在面对函数时想:
- "这么多函数,我怎么记得住?"
- "什么时候用哪个数据类型啊?"
- "复杂的数据转换该怎么处理?"
别担心! 函数就像工具,用得多了自然就熟练了 ✨
🔧 想象数据类型和函数就像厨房用具
做菜时的工具选择:
- 🔪 字符串函数 = 切菜刀(处理文本数据)
- 🥄 数值函数 = 量杯(处理数字计算)
- ⏰ 日期函数 = 定时器(处理时间数据)
- 🍲 聚合函数 = 大锅(汇总统计数据)
- 🎯 条件函数 = 调味料(根据条件处理)
掌握了这些"工具",你就能烹饪出完美的数据分析! 🌟
🎯 Impala数据类型全景图
📊 数据类型分类体系
%%{init: {"theme":"base","themeVariables":{"fontFamily":"PingFang SC, -apple-system, Source Han Serif SC, serif","fontSize":"16px","background":"#FDFBF5","primaryColor":"#FDFBF5","primaryTextColor":"#2D2A26","primaryBorderColor":"#6E6A60","secondaryColor":"#E8EFE8","secondaryBorderColor":"#8FA890","secondaryTextColor":"#2D2A26","tertiaryColor":"#FDFBF5","tertiaryBorderColor":"#9A9488","tertiaryTextColor":"#6E6A60","lineColor":"#6E6A60","textColor":"#2D2A26","mainBkg":"#FDFBF5","nodeBorder":"#2D5A3D","clusterBkg":"#F3EEDF","clusterBorder":"#9A9488","edgeLabelBackground":"#FDFBF5"},"flowchart":{"htmlLabels":true,"curve":"basis","padding":20,"nodeSpacing":60,"rankSpacing":70,"useMaxWidth":false},"themeCSS":".node rect, .node polygon, .node circle { stroke-width: 1.5px; } .edgePath .path { stroke-width: 1.5px; } .cluster-label .nodeLabel, .cluster-label foreignObject { color: #2D2A26 !important; } .edgeLabel, .edgeLabel foreignObject { color: #2D2A26 !important; background-color: #FDFBF5; } .edgeLabel rect { fill: #FDFBF5; }"}}%%
flowchart TD
A[Impala数据类型]
A --> B[🔢 数值类型]
A --> C[📝 文本类型]
A --> D[⏰ 日期时间类型]
A --> E[✅ 布尔类型]
A --> F[📦 复杂类型]
B --> B1[TINYINT<br/>-128到127]
B --> B2[SMALLINT<br/>-32,768到32,767]
B --> B3[INT<br/>-2,147,483,648到2,147,483,647]
B --> B4[BIGINT<br/>更大的整数]
B --> B5[FLOAT<br/>单精度浮点]
B --> B6[DOUBLE<br/>双精度浮点]
B --> B7[DECIMAL p,s<br/>精确小数]
C --> C1[STRING<br/>可变长度字符串]
C --> C2[CHAR n<br/>固定长度字符串]
C --> C3[VARCHAR n<br/>可变长度限制字符串]
D --> D1[TIMESTAMP<br/>日期和时间]
D --> D2[DATE<br/>仅日期]
E --> E1[BOOLEAN<br/>TRUE/FALSE]
F --> F1[ARRAY<br/>数组类型]
F --> F2[MAP<br/>键值对]
F --> F3[STRUCT<br/>结构体]
style A fill:#e1f5fe,stroke:#0277bd
style B fill:#f3e5f5,stroke:#7b1fa2
style C fill:#fff3e0,stroke:#ef6c00
style D fill:#e8f5e8,stroke:#2e7d32
style E fill:#fce4ec,stroke:#c2185b
style F fill:#f9fbe7,stroke:#689f38
🎯 数据类型选择指南
| 数据场景 | 推荐类型 | 说明 | 示例 |
|---|---|---|---|
| 用户ID | STRING | 可能包含字母数字 | 'U12345', 'USER_001' |
| 年龄 | TINYINT | 0-127范围足够 | 25, 45, 67 |
| 销售额 | DECIMAL(12,2) | 精确货币计算 | 12345.67 |
| 点击率 | DOUBLE | 精度要求高 | 0.0234567 |
| 用户名 | VARCHAR(50) | 限制长度防止异常 | '张三', 'John Smith' |
| 描述 | STRING | 长度不确定 | 长篇文本描述 |
| 创建时间 | TIMESTAMP | 完整时间信息 | '2024-01-15 14:30:25' |
| 生日 | DATE | 只需日期 | '1990-05-20' |
🔢 数值类型详解
📊 创建测试数据
-- 创建数值类型测试表
CREATE TABLE numeric_examples (
id INT,
tiny_num TINYINT,
small_num SMALLINT,
big_num BIGINT,
float_num FLOAT,
double_num DOUBLE,
decimal_money DECIMAL(10,2),
decimal_rate DECIMAL(5,4)
) STORED AS PARQUET;
-- 插入测试数据
INSERT INTO numeric_examples VALUES
(1, 100, 30000, 9223372036854775807, 3.14, 3.14159265359, 12345.67, 0.1234),
(2, -50, -15000, -1000000000000, 2.71, 2.71828182846, 98765.43, 0.9876),
(3, 127, 32767, 0, 1.41, 1.41421356237, 0.01, 0.0001);
COMPUTE STATS numeric_examples;
🧮 数值函数应用
1. 基础数学函数
-- 1.1 基础数学运算
SELECT
id,
decimal_money,
-- 基础运算
decimal_money + 1000 AS 加法运算,
decimal_money * 1.1 AS 乘法运算,
decimal_money / 100 AS 除法运算,
decimal_money % 100 AS 取模运算,
-- 数学函数
ABS(decimal_money - 50000) AS 绝对值,
ROUND(decimal_money, 0) AS 四舍五入整数,
ROUND(decimal_money, 1) AS 四舍五入一位小数,
CEIL(decimal_money) AS 向上取整,
FLOOR(decimal_money) AS 向下取整,
TRUNCATE(decimal_money, 1) AS 截断一位小数
FROM numeric_examples;
-- 1.2 高级数学函数
SELECT
id,
double_num,
SQRT(double_num) AS 平方根,
POWER(double_num, 2) AS 平方,
EXP(double_num) AS e的幂,
LN(double_num) AS 自然对数,
LOG10(double_num) AS 常用对数,
SIN(double_num) AS 正弦值,
COS(double_num) AS 余弦值,
TAN(double_num) AS 正切值
FROM numeric_examples
WHERE double_num > 0; -- 避免负数或零的对数运算
2. 数值转换和格式化
-- 2.1 数据类型转换
SELECT
id,
decimal_money,
CAST(decimal_money AS INT) AS 转为整数,
CAST(decimal_money AS STRING) AS 转为字符串,
CAST(decimal_money AS BIGINT) AS 转为长整数,
-- 安全转换(避免溢出)
CASE
WHEN decimal_money > 32767 THEN 32767
WHEN decimal_money < -32768 THEN -32768
ELSE CAST(decimal_money AS SMALLINT)
END AS 安全转为SMALLINT
FROM numeric_examples;
-- 2.2 数值格式化
SELECT
id,
decimal_money,
FORMAT_NUMBER(decimal_money, 0) AS 千分位整数,
FORMAT_NUMBER(decimal_money, 2) AS 千分位两位小数,
LPAD(CAST(id AS STRING), 5, '0') AS ID左补零,
RPAD(CAST(decimal_money AS STRING), 10, '*') AS 右补星号
FROM numeric_examples;
3. 统计和聚合函数
-- 3.1 基础统计函数
SELECT
COUNT(*) AS 记录数,
COUNT(decimal_money) AS 非空金额数,
SUM(decimal_money) AS 金额总和,
AVG(decimal_money) AS 平均金额,
MIN(decimal_money) AS 最小金额,
MAX(decimal_money) AS 最大金额,
-- 标准差和方差
STDDEV(decimal_money) AS 标准差,
VARIANCE(decimal_money) AS 方差,
-- 中位数(近似)
APPX_MEDIAN(decimal_money) AS 近似中位数
FROM numeric_examples;
-- 3.2 分组统计
SELECT
CASE
WHEN decimal_money < 10000 THEN '小额'
WHEN decimal_money < 50000 THEN '中额'
ELSE '大额'
END AS 金额等级,
COUNT(*) AS 数量,
AVG(decimal_money) AS 平均金额,
SUM(decimal_money) AS 总金额
FROM numeric_examples
GROUP BY
CASE
WHEN decimal_money < 10000 THEN '小额'
WHEN decimal_money < 50000 THEN '中额'
ELSE '大额'
END;
📝 字符串类型和函数
📋 创建字符串测试数据
-- 创建字符串测试表
CREATE TABLE string_examples (
id INT,
name STRING,
email STRING,
phone STRING,
address STRING,
description STRING,
tags STRING
) STORED AS PARQUET;
-- 插入测试数据
INSERT INTO string_examples VALUES
(1, '张三', 'zhangsan@gmail.com', '13800138001', '北京市朝阳区建国路88号', '优秀员工,工作认真负责', 'VIP,老客户,推荐'),
(2, 'John Smith', 'john.smith@company.com', '+86-13800138002', '上海市浦东新区陆家嘴金融中心', 'International customer with high value', 'International,High-Value'),
(3, '李四', 'lisi@163.com', '138-0013-8003', '广州市天河区珠江新城', NULL, '新客户'),
(4, '王五公司', 'contact@wangwu.com', '400-123-4567', '深圳市南山区科技园', '大客户,年采购额超过100万', 'Enterprise,Big-Client'),
(5, '', 'empty@test.com', NULL, '', '测试用空数据', '');
COMPUTE STATS string_examples;
🔤 字符串基础函数
1. 字符串信息函数
-- 1.1 字符串长度和基本信息
SELECT
id,
name,
LENGTH(name) AS 名称长度,
CHAR_LENGTH(name) AS 字符长度,
BIT_LENGTH(name) AS 位长度,
email,
LENGTH(email) AS 邮箱长度,
description,
COALESCE(LENGTH(description), 0) AS 描述长度
FROM string_examples;
-- 1.2 字符串判断函数
SELECT
id,
name,
name = '' AS 是否空字符串,
name IS NULL AS 是否NULL,
name IS NOT NULL AND name != '' AS 是否有效字符串,
LENGTH(TRIM(name)) > 0 AS 去空格后是否有内容
FROM string_examples;
2. 字符串大小写和修饰
-- 2.1 大小写转换
SELECT
id,
name,
UPPER(name) AS 大写名称,
LOWER(name) AS 小写名称,
INITCAP(name) AS 首字母大写,
email,
LOWER(email) AS 标准邮箱格式
FROM string_examples;
-- 2.2 字符串修饰和填充
SELECT
id,
name,
TRIM(name) AS 去除首尾空格,
LTRIM(name) AS 去除左侧空格,
RTRIM(name) AS 去除右侧空格,
LPAD(CAST(id AS STRING), 5, '0') AS ID左补零,
RPAD(name, 20, '-') AS 名称右补横线,
REVERSE(name) AS 反转字符串
FROM string_examples;
3. 字符串截取和查找
-- 3.1 字符串截取
SELECT
id,
name,
SUBSTR(name, 1, 2) AS 前两个字符,
SUBSTR(name, -2) AS 后两个字符,
LEFT(name, 3) AS 左侧3个字符,
RIGHT(name, 3) AS 右侧3个字符,
email,
SUBSTR(email, 1, LOCATE('@', email) - 1) AS 邮箱用户名,
SUBSTR(email, LOCATE('@', email) + 1) AS 邮箱域名
FROM string_examples
WHERE email IS NOT NULL AND LOCATE('@', email) > 0;
-- 3.2 字符串查找和位置
SELECT
id,
name,
email,
LOCATE('@', email) AS at符号位置,
LOCATE('.', email) AS 点号位置,
LOCATE('com', email) AS com位置,
description,
LOCATE('客户', description) AS 客户一词位置,
-- 查找是否包含特定字符
email LIKE '%gmail%' AS 是否gmail邮箱,
email LIKE '%@%.com' AS 是否com域名
FROM string_examples;
🔧 字符串高级处理
1. 字符串拼接和替换
-- 1.1 字符串拼接
SELECT
id,
name,
email,
phone,
-- 拼接函数
CONCAT(name, ' (', email, ')') AS 名称邮箱,
CONCAT_WS(' | ', name, email, phone) AS 管道分隔信息,
-- 条件拼接
CONCAT(
name,
CASE WHEN email IS NOT NULL THEN CONCAT(' <', email, '>') ELSE '' END
) AS 完整联系信息
FROM string_examples;
-- 1.2 字符串替换
SELECT
id,
phone,
-- 基础替换
REPLACE(phone, '-', '') AS 去除横线电话,
REPLACE(phone, '+86-', '') AS 去除国家代码,
description,
REPLACE(description, '客户', '用户') AS 替换客户为用户,
tags,
REPLACE(tags, ',', ' | ') AS 标签管道分隔
FROM string_examples;
2. 正则表达式处理
-- 2.1 正则表达式匹配
SELECT
id,
email,
phone,
-- 正则匹配
email RLIKE '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' AS 邮箱格式正确,
phone RLIKE '^1[3-9][0-9]{9}$' AS 手机号格式正确,
phone RLIKE '^400-[0-9]{3}-[0-9]{4}$' AS 400号码格式,
-- 提取内容
REGEXP_EXTRACT(email, '^([^@]+)@', 1) AS 提取用户名,
REGEXP_EXTRACT(email, '@([^.]+)', 1) AS 提取域名前缀,
REGEXP_EXTRACT(phone, '([0-9]{3})', 1) AS 提取前三位数字
FROM string_examples
WHERE email IS NOT NULL;
-- 2.2 正则表达式替换
SELECT
id,
phone,
description,
-- 正则替换
REGEXP_REPLACE(phone, '[^0-9]', '') AS 只保留数字,
REGEXP_REPLACE(phone, '^\\+86-?', '') AS 去除国际代码,
REGEXP_REPLACE(description, '[,。!?]', ',') AS 统一标点符号,
-- 复杂正则处理
REGEXP_REPLACE(email, '([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)', '***@\\2') AS 隐藏邮箱用户名
FROM string_examples;
3. 字符串分割(模拟)
-- 3.1 字符串分割(模拟)
SELECT
id,
tags,
-- 使用LOCATE和SUBSTR模拟分割
CASE
WHEN LOCATE(',', tags) > 0
THEN SUBSTR(tags, 1, LOCATE(',', tags) - 1)
ELSE tags
END AS 第一个标签,
CASE
WHEN LOCATE(',', tags) > 0
THEN SUBSTR(tags, LOCATE(',', tags) + 1)
ELSE NULL
END AS 剩余标签,
-- 计算标签数量(逗号数量+1)
LENGTH(tags) - LENGTH(REPLACE(tags, ',', '')) + 1 AS 标签数量
FROM string_examples
WHERE tags IS NOT NULL AND tags != '';
⏰ 日期时间类型和函数
📅 创建日期时间测试数据
-- 创建日期时间测试表
CREATE TABLE datetime_examples (
id INT,
event_name STRING,
event_date DATE,
event_timestamp TIMESTAMP,
duration_minutes INT
) STORED AS PARQUET;
-- 插入测试数据
INSERT INTO datetime_examples VALUES
(1, '项目启动会', '2024-01-15', '2024-01-15 09:00:00', 60),
(2, '客户拜访', '2024-01-16', '2024-01-16 14:30:00', 120),
(3, '月度总结', '2024-01-31', '2024-01-31 16:00:00', 90),
(4, '培训会议', '2024-02-05', '2024-02-05 10:00:00', 180),
(5, '年度规划', '2024-12-01', '2024-12-01 09:30:00', 240);
COMPUTE STATS datetime_examples;
📆 日期时间基础函数
1. 当前时间函数
-- 1.1 获取当前时间
SELECT
NOW() AS 当前时间戳,
CURRENT_TIMESTAMP() AS 当前时间戳2,
CURRENT_DATE() AS 当前日期,
UNIX_TIMESTAMP() AS Unix时间戳,
-- 时区相关
UTC_TIMESTAMP() AS UTC时间,
FROM_UNIXTIME(UNIX_TIMESTAMP()) AS 从Unix时间戳转换;
-- 1.2 时间计算基础
SELECT
id,
event_name,
event_date,
event_timestamp,
-- 当前时间与事件时间的差异
DATEDIFF(CURRENT_DATE(), event_date) AS 距今天数,
DATEDIFF(event_date, CURRENT_DATE()) AS 距事件天数,
-- 时间戳差异(秒)
UNIX_TIMESTAMP() - UNIX_TIMESTAMP(event_timestamp) AS 距现在秒数
FROM datetime_examples;
2. 日期时间提取函数
-- 2.1 日期组件提取
SELECT
id,
event_name,
event_date,
event_timestamp,
-- 日期组件
YEAR(event_date) AS 年份,
MONTH(event_date) AS 月份,
DAY(event_date) AS 日期,
DAYOFWEEK(event_date) AS 星期几_数字,
DAYNAME(event_date) AS 星期几_名称,
DAYOFYEAR(event_date) AS 一年中第几天,
WEEKOFYEAR(event_date) AS 一年中第几周,
-- 时间组件
HOUR(event_timestamp) AS 小时,
MINUTE(event_timestamp) AS 分钟,
SECOND(event_timestamp) AS 秒
FROM datetime_examples;
-- 2.2 日期格式化
SELECT
id,
event_date,
event_timestamp,
-- 日期格式化
DATE_FORMAT(event_date, 'yyyy-MM-dd') AS 标准日期格式,
DATE_FORMAT(event_date, 'yyyy年MM月dd日') AS 中文日期格式,
DATE_FORMAT(event_date, 'MM/dd/yyyy') AS 美式日期格式,
-- 时间戳格式化
DATE_FORMAT(event_timestamp, 'yyyy-MM-dd HH:mm:ss') AS 标准时间格式,
DATE_FORMAT(event_timestamp, 'HH:mm') AS 时分格式
FROM datetime_examples;
3. 日期时间计算
-- 3.1 日期加减运算
SELECT
id,
event_name,
event_date,
duration_minutes,
-- 日期加减
DATE_ADD(event_date, 7) AS 一周后日期,
DATE_SUB(event_date, 7) AS 一周前日期,
ADD_MONTHS(event_date, 1) AS 一个月后,
ADD_MONTHS(event_date, -1) AS 一个月前,
-- 时间戳加减
DATE_ADD(event_timestamp, INTERVAL duration_minutes MINUTE) AS 结束时间,
DATE_ADD(event_timestamp, INTERVAL 1 HOUR) AS 一小时后,
DATE_SUB(event_timestamp, INTERVAL 30 MINUTE) AS 半小时前
FROM datetime_examples;
-- 3.2 日期范围和工作日计算
SELECT
id,
event_date,
-- 日期范围判断
event_date BETWEEN '2024-01-01' AND '2024-01-31' AS 是否一月份,
MONTH(event_date) IN (1, 2, 12) AS 是否冬季月份,
-- 工作日判断(1=周日,2=周一...7=周六)
DAYOFWEEK(event_date) BETWEEN 2 AND 6 AS 是否工作日,
CASE DAYOFWEEK(event_date)
WHEN 1 THEN '周末'
WHEN 7 THEN '周末'
ELSE '工作日'
END AS 日期类型,
-- 月初月末
DATE_FORMAT(event_date, 'yyyy-MM-01') AS 月初日期,
LAST_DAY(event_date) AS 月末日期
FROM datetime_examples;
🎯 日期时间高级应用
1. 时间段分析
-- 1.1 时间段分组分析
SELECT
CASE
WHEN MONTH(event_date) IN (1, 2, 3) THEN 'Q1'
WHEN MONTH(event_date) IN (4, 5, 6) THEN 'Q2'
WHEN MONTH(event_date) IN (7, 8, 9) THEN 'Q3'
ELSE 'Q4'
END AS 季度,
CASE
WHEN HOUR(event_timestamp) BETWEEN 6 AND 11 THEN '上午'
WHEN HOUR(event_timestamp) BETWEEN 12 AND 17 THEN '下午'
WHEN HOUR(event_timestamp) BETWEEN 18 AND 23 THEN '晚上'
ELSE '深夜'
END AS 时间段,
COUNT(*) AS 事件数量,
AVG(duration_minutes) AS 平均时长
FROM datetime_examples
GROUP BY
CASE
WHEN MONTH(event_date) IN (1, 2, 3) THEN 'Q1'
WHEN MONTH(event_date) IN (4, 5, 6) THEN 'Q2'
WHEN MONTH(event_date) IN (7, 8, 9) THEN 'Q3'
ELSE 'Q4'
END,
CASE
WHEN HOUR(event_timestamp) BETWEEN 6 AND 11 THEN '上午'
WHEN HOUR(event_timestamp) BETWEEN 12 AND 17 THEN '下午'
WHEN HOUR(event_timestamp) BETWEEN 18 AND 23 THEN '晚上'
ELSE '深夜'
END;
-- 1.2 时间序列生成(原稿使用递归CTE;Impala不支持此写法,以下代码保留作待改写示例,不可直接执行)
WITH RECURSIVE date_series AS (
SELECT DATE '2024-01-01' AS date_value
UNION ALL
SELECT DATE_ADD(date_value, 1)
FROM date_series
WHERE date_value < DATE '2024-01-31'
)
SELECT
ds.date_value AS 日期,
DAYNAME(ds.date_value) AS 星期,
de.event_name AS 事件名称,
CASE WHEN de.event_date IS NOT NULL THEN '有事件' ELSE '无事件' END AS 事件状态
FROM date_series ds
LEFT JOIN datetime_examples de ON ds.date_value = de.event_date
ORDER BY ds.date_value;
📦 复杂数据类型
🗂️ 数组(ARRAY)类型
-- 创建包含数组的表
CREATE TABLE array_examples (
id INT,
name STRING,
skills ARRAY<STRING>,
scores ARRAY<INT>
) STORED AS PARQUET;
-- 插入数组数据
INSERT INTO array_examples VALUES
(1, '张三', ARRAY('Java', 'Python', 'SQL'), ARRAY(85, 90, 95)),
(2, '李四', ARRAY('JavaScript', 'React', 'Node.js'), ARRAY(88, 92, 87)),
(3, '王五', ARRAY('Python', 'Machine Learning', 'SQL'), ARRAY(92, 89, 93));
-- 数组函数应用
SELECT
id,
name,
skills,
scores,
-- 数组大小
SIZE(skills) AS 技能数量,
SIZE(scores) AS 分数数量,
-- 数组整列展示(不是首个元素访问;执行支持仍需按目标版本核对)
skills AS 技能数组,
scores AS 分数数组,
-- 数组包含检查
ARRAY_CONTAINS(skills, 'Python') AS 是否会Python,
ARRAY_CONTAINS(skills, 'Java') AS 是否会Java
FROM array_examples;
🗝️ 映射(MAP)类型
-- 创建包含MAP的表
CREATE TABLE map_examples (
id INT,
name STRING,
attributes MAP<STRING, STRING>
) STORED AS PARQUET;
-- 注意:以下为原稿的MAP构造与插入示例,不能作为Impala已支持的写入语法直接执行;需改用目标版本支持的复杂类型装载方式
INSERT INTO map_examples VALUES
(1, '产品A', MAP('category', 'electronics', 'brand', 'Apple', 'color', 'black')),
(2, '产品B', MAP('category', 'clothing', 'brand', 'Nike', 'size', 'L'));
-- MAP函数应用
SELECT
id,
name,
attributes,
-- 获取MAP中的值
attributes['category'] AS 类别,
attributes['brand'] AS 品牌,
attributes['color'] AS 颜色,
-- MAP大小
SIZE(attributes) AS 属性数量
FROM map_examples;
🔄 条件和转换函数
🎯 条件逻辑函数
-- 使用之前的sales_records表进行演示
SELECT
order_id,
customer_name,
unit_price,
quantity,
discount_rate,
-- CASE WHEN 复杂条件
CASE
WHEN unit_price * quantity >= 20000 THEN '大订单'
WHEN unit_price * quantity >= 10000 THEN '中订单'
WHEN unit_price * quantity >= 5000 THEN '普通订单'
ELSE '小订单'
END AS 订单等级,
-- 简单条件函数
IF(discount_rate > 0.1, '高折扣', '正常折扣') AS 折扣类型,
-- NULL处理
COALESCE(discount_rate, 0) AS 实际折扣率,
NVL(discount_rate, 0) AS 折扣率_NVL,
discount_rate IS NULL AS 是否空折扣,
NULLIF(discount_rate, 0) AS 非零折扣率,
-- 最大最小值
GREATEST(unit_price, quantity * 100) AS 最大值,
LEAST(unit_price, quantity * 1000) AS 最小值
FROM sales_records;
🔀 数据转换函数
-- 数据类型转换综合示例
SELECT
order_id,
-- 字符串转数值
CAST('123.45' AS DECIMAL(10,2)) AS 字符串转小数,
CAST('2024' AS INT) AS 字符串转整数,
-- 数值转字符串
CAST(unit_price AS STRING) AS 价格转字符串,
-- 日期转换
CAST('2024-01-15' AS DATE) AS 字符串转日期,
CAST(order_date AS TIMESTAMP) AS 日期转时间戳,
-- 格式化转换
DATE_FORMAT(order_date, 'yyyyMMdd') AS 日期转数字格式,
UNIX_TIMESTAMP(order_date) AS 日期转Unix时间戳
FROM sales_records
LIMIT 3;
🎉 数据类型与函数学习收获
success 🌟 **恭喜!你已经掌握了Impala数据处理的核心工具!**
你现在具备的能力:
- ✅ 类型选择:能够为不同场景选择合适的数据类型
- ✅ 数值处理:掌握数学计算、统计分析、格式化等技能
- ✅ 文本处理:字符串操作、正则表达式、文本分析
- ✅ 时间处理:日期计算、时间分析、时间序列处理
- ✅ 复杂类型:数组、映射等复杂数据结构的处理
- ✅ 条件逻辑:灵活的条件判断和数据转换
完成练习并核对目标版本后,你可以进一步尝试组合这些工具处理更复杂的数据;实际应用仍需验证类型、函数兼容性和业务规则。 🚀
🎯 实战能力检验
完成以下挑战来验证你的学习成果:
-- 🎯 挑战1:综合数据清洗
-- 清洗客户电话号码,统一格式为:138-0013-8001
SELECT
id,
name,
phone AS 原始电话,
CASE
WHEN phone IS NULL THEN NULL
WHEN LENGTH(REGEXP_REPLACE(phone, '[^0-9]', '')) = 11
THEN CONCAT(
SUBSTR(REGEXP_REPLACE(phone, '[^0-9]', ''), 1, 3),
'-',
SUBSTR(REGEXP_REPLACE(phone, '[^0-9]', ''), 4, 4),
'-',
SUBSTR(REGEXP_REPLACE(phone, '[^0-9]', ''), 8, 4)
)
ELSE phone
END AS 标准电话格式
FROM string_examples;
-- 🎯 挑战2:复杂时间分析
-- 分析事件的时间分布和工作效率
SELECT
event_name,
event_date,
DAYNAME(event_date) AS 星期,
HOUR(event_timestamp) AS 开始小时,
duration_minutes,
-- 计算结束时间
DATE_ADD(event_timestamp, INTERVAL duration_minutes MINUTE) AS 结束时间,
-- 判断是否工作时间
CASE
WHEN DAYOFWEEK(event_date) BETWEEN 2 AND 6
AND HOUR(event_timestamp) BETWEEN 9 AND 17
THEN '工作时间'
ELSE '非工作时间'
END AS 时间类型,
-- 效率评级
CASE
WHEN duration_minutes <= 60 THEN '高效'
WHEN duration_minutes <= 120 THEN '正常'
ELSE '耗时'
END AS 效率评级
FROM datetime_examples;
-- 🎯 挑战3:综合业务分析
-- 结合多种函数进行复杂业务分析
SELECT
customer_name,
COUNT(*) AS 订单数量,
SUM(unit_price * quantity) AS 订单总金额,
AVG(unit_price * quantity) AS 平均订单金额,
MAX(order_date) AS 最近订单日期,
-- 客户价值评级
CASE
WHEN SUM(unit_price * quantity) >= 50000 THEN 'VIP客户'
WHEN SUM(unit_price * quantity) >= 20000 THEN '重要客户'
WHEN SUM(unit_price * quantity) >= 10000 THEN '普通客户'
ELSE '潜在客户'
END AS 客户等级,
-- 活跃度分析
DATEDIFF(CURRENT_DATE(), MAX(order_date)) AS 距离最近订单天数,
CASE
WHEN DATEDIFF(CURRENT_DATE(), MAX(order_date)) <= 30 THEN '活跃'
WHEN DATEDIFF(CURRENT_DATE(), MAX(order_date)) <= 90 THEN '一般'
ELSE '不活跃'
END AS 活跃度,
-- 客户标识生成
CONCAT(
UPPER(LEFT(customer_name, 2)),
'-',
LPAD(CAST(COUNT(*) AS STRING), 3, '0')
) AS 客户编码
FROM sales_records
GROUP BY customer_name
ORDER BY 订单总金额 DESC;
🎯 下一步学习建议
立即练习:
- [ ] 尝试处理真实的脏数据
- [ ] 练习复杂的数据转换场景
- [ ] 体验大数据量下的函数性能
继续学习:
quote 💭 **数据处理的艺术**
数据类型和函数是数据分析的基石:
- 🎯 精确选择:选择合适的数据类型保证数据质量
- 🔧 灵活运用:组合使用函数解决复杂业务问题
- ⚡ 性能考虑:了解函数性能影响,优化查询效率
- 🎨 创新思维:用函数组合创造性地解决数据处理难题
掌握了这些工具,你就能在数据的海洋中自由遨游! ✨
创建时间:2024-12-11
温度指数:⭐⭐⭐⭐⭐ (实用性强,示例丰富)
预计学习时长:90-120分钟
下一步学习:表操作与DDL → 查询优化
#Impala #数据类型 #函数应用 #字符串处理 #日期时间 #数据转换 #实战技能