操作数组可不只是创建和存储,有时候你还得把单个元素拿出来,或者分析一下数组内容。PostgreSQL 给你准备了好几个内置函数来搞定这些事。下面咱们一个个来看。
unnest() 函数:数组拆包
unnest() 这个函数就是把数组拆开,把每个元素变成单独一行。要是你想把数组里的数据当表来用,这个就超有用。
例子 1:简单拆包数组
比如说,我们有个装着学院名字的数组:
SELECT ARRAY['计算机科学', '数学', '物理'] AS 学院们;
现在想把每个元素都单独拿出来一行,用 unnest():
SELECT unnest(ARRAY['计算机科学', '数学', '物理']) AS 学院;
结果:
| 学院 |
|---|
| 计算机科学 |
| 数学 |
| 物理 |
例子 2:在表里拆包数组
假设我们有个表叫 courses:
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_name TEXT,
tags TEXT[]
);
INSERT INTO courses (course_name, tags)
VALUES
('算法', ARRAY['编程', '计算机科学']),
('线性代数', ARRAY['数学', '代数']),
('基础物理', ARRAY['物理', '通用']);
现在我们要把所有 tag 都拆出来:
SELECT course_name, unnest(tags) AS tag
FROM courses;
结果:
| course_name | tag |
|---|---|
| 算法 | 编程 |
| 算法 | 计算机科学 |
| 线性代数 | 数学 |
| 线性代数 | 代数 |
| 基础物理 | 物理 |
| 基础物理 | 通用 |
你看,每个数组元素都变成了表里的一行。
array_length() 函数:获取数组长度
第二个很重要的数组操作函数就是 array_length()。它能返回数组的长度(也就是元素个数),你还可以指定维度。
例子 1:一维数组的元素个数
比如有个数组:
SELECT ARRAY['苹果', '香蕉', '橙子'] AS 水果们;
想知道数组里有几个水果:
SELECT array_length(ARRAY['苹果', '香蕉', '橙子'], 1) AS 长度;
结果:
| 长度 |
|---|
| 3 |
这里 1 表示数组的第一个维度。PostgreSQL 里的数组可以有多维(比如二维数组),不过这个以后再说。
例子 2:表里数组的元素个数
来看看每门课有多少个 tag:
SELECT course_name, array_length(tags, 1) AS tag数量
FROM courses;
结果:
| course_name | tag数量 |
|---|---|
| 算法 | 2 |
| 线性代数 | 2 |
| 基础物理 | 2 |
这个函数直接告诉你:“嘿,这里有两个元素!”,分析数据的时候很方便。
array_position() 函数:查找数组里的值
现在,假如你要在数组里找某个元素。array_position() 就能帮你搞定:它会返回元素第一次出现的位置。
例子 1:查找元素
比如有个数组:
SELECT ARRAY['红色', '蓝色', '绿色', '黄色'] AS 颜色们;
来找一下“蓝色”在哪个位置:
SELECT array_position(ARRAY['红色', '蓝色', '绿色', '黄色'], '蓝色') AS 位置;
结果:
| 位置 |
|---|
| 2 |
如果找不到元素,函数会返回 NULL。来试试:
SELECT array_position(ARRAY['红色', '蓝色', '绿色', '黄色'], '黑色') AS 位置;
结果:
| 位置 |
|---|
| NULL |
例子 2:在表里的数组查找
你想知道哪门课有 tag “计算机科学”。先查一下:
SELECT course_name, array_position(tags, '计算机科学') AS 位置
FROM courses;
结果:
| course_name | 位置 |
|---|---|
| 算法 | 2 |
| 线性代数 | NULL |
| 基础物理 | NULL |
现在加个过滤,只保留有这个 tag 的行:
SELECT course_name
FROM courses
WHERE array_position(tags, '计算机科学') IS NOT NULL;
结果:
| course_name |
|---|
| 算法 |
array_position() 让你能很快在数组里找到数据,是 PostgreSQL 里操作数组的核心函数之一。
这些函数的实际用法
unnest()— 用来把数组变成多行。分析数据、做报表、处理 tag 都离不开它。array_length()— 检查数组长度超方便。比如你可以用它做数据校验:看看数组是不是空的。array_position()— 查找元素的神器,不管是商品分类、学生参与的项目,还是描述里的关键词都能用。
用这些函数时常见的坑
unnest()如果你同时对多个列的数组用,会让行数翻倍。可以用JOIN LATERAL或CROSS JOIN解决,记得注意下。array_length()对空数组会返回NULL。如果你的数组可能是空的,记得单独判断一下。array_position()如果找不到元素会返回NULL,所以写过滤条件时最好加上IS NOT NULL。
实际开发里的例子
PostgreSQL 里的数组不是纸上谈兵,实际项目里用起来超方便。比如你写博客,每篇文章有一堆 tag —— 用数组存,查找、筛选、做热门分类都很 easy。
再比如你分析用户行为,用户可能会选好几个感兴趣的课程或产品。把这些偏好都放数组里,处理起来也很顺手。
还有数组也能帮你做数据校验:用 array_length() 限制元素个数,比如不让用户选超过五个选项啥的。
GO TO FULL VERSION