postgresql数组查询

测试数据

CREATE TABLE arr_test (
    name            text,
    color  varchar[],
    size varchar[]
);
INSERT INTO arr_test
    VALUES ('adult_f','{"grey","black","white"}','{"s","m","l","xl","xxl"}'),
    ('adult_w','{"red","black","white","grey","blue"}','{"s","m","l","xl"}'),
    ('child_a','{"red","black","green","pink"}','{"s","m","l"}'),
    ('child_b','{}','{"m","l"}'), --空数组
    ('child_c',Null,'{"m"}'),
    ('child_d',array[''],Null),--数组中有一个元素,是空字符串
    ('test','{""}',null)--数组中有一个元素,是空字符串

下标访问

可通过下标进行访问:fileName[int],若指定的下标越界或者数组本身为空,返回null
需要注意的是:空数组和数组中有一个空字符串的区别,实际查看库的时候看着都是空的,但是空数组计算的长度是0,有一个空字符串的数组计算长度是1

--下标访问,从1开始    
 SELECT name,color[1] FROM arr_test;
 -------运行结果-----------
 #	name	color
1	adult_f	grey
2	adult_w	red
3	child_a	red
4	child_b	[NULL]
5	child_c	[NULL]
6	child_d	
7	test	

--切片(如果下标错误或者数组值本身为空,返回的是空值(null)
 SELECT name,color[1:4] FROM arr_test;
  -------运行结果-----------
#	name	color
1	adult_f	{grey,black,white}
2	adult_w	{red,black,white,grey}
3	child_a	{red,black,green,pink}
4	child_b	{}
5	child_c	NULL
6	child_d	{}
7	test	{}

数组函数

  • 数组长度array_length
    计算数组的长度
--array_length返回一个指定数组维度的长度,1表示第一维度上数组的长度,如果指定的维度不存在或者是空数组则返回null
SELECT name,array_length(color,1) FROM arr_test;
  -------运行结果-----------
  #	name	array_length
1	adult_f	3
2	adult_w	5
3	child_a	4
4	child_b	[NULL]
5	child_c	[NULL]
6	child_d	1
7	test	1
  • 数组转为字符串array_to_string
--array_to_string将color字段转为字符串,以逗号分隔
select name,array_to_string(color,',') from arr_test 
------运行结果---------
#	name	array_to_string
1	adult_f	grey,black,white
2	adult_w	red,black,white,grey,blue
3	child_a	red,black,green,pink
4	child_b	
5	child_c	[NULL]
6	child_d	
7	test	
  • 查询指定元素在数组中的位置array_positionarray_positions
    查询出元素在数组中第一次出现的位置(array_position) 或者出现的所有位置(array_positions)
--array_position:在一个 数组中搜索特定值,返回第一次出现的位置,若不存在返回空值
SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');
------运行结果---------
#	array_position
1	2

--array_positions:在一个 数组中搜索特定值,返回出现的位置,若不存在返回{}
SELECT array_positions(ARRAY['sun','mon','tue','wed','thu','fri','mon'], 'mon');
------运行结果---------
#	array_positions
1	{2,7}

SELECT array_positions(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'm9on');
------运行结果---------
#	array_positions
1	{}

数组操作符

操作符描述例子结果
=等于ARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]t
<>不等于ARRAY[1,2,3] <> ARRAY[1,2,4]t
<小于ARRAY[1,2,3] < ARRAY[1,2,4]t
>大于ARRAY[1,4,3] > ARRAY[1,2,4]t
<=小于等于ARRAY[1,2,3] <= ARRAY[1,2,3]t
>=大于等于ARRAY[1,4,3] >= ARRAY[1,4,3]t
@>包含ARRAY[1,4,3] @> ARRAY[3,1,3]t
<@被包含ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6]t
&&重叠 ,有相同的元素ARRAY[1,4,3] && ARRAY[2,1]t
||数组和数组连接ARRAY[1,2,3] ||ARRAY[4,5,6]t等同array_cat(anyarray, anyarray)
||数组到元素连接ARRAY[4,5,6] || 7t等同array_append(anyarray, anyelement)
||元素到数组连接3 || ARRAY[4,5,6]t等同array_prepend(anyelement, anyarray)
  • &&操作符
    测试代码如下,进行查询后会报错:
select * from arr_test where array['red']&&color
------运行结果---------
org.jkiss.dbeaver.model.sql.DBSQLException: SQL 错误 [42883]: 错误: 操作符不存在: text[] && character varying[]
  建议:No operator matches the given name and argument types. You might need to add explicit type casts.

根据错误信息是两边数组类型不一样,需要进行转换,可修改为以下几种方式:

#方式一
select * from arr_test where array['red']::character varying[]&&color
#方式二
select * from arr_test where cast(array['red'] as varchar[])&&color
#方式三
select * from arr_test where '{red,blue}'&&color

输出结果:
查询结果
学习文档:http://www.postgres.cn/docs/13/arrays.html

### PostgreSQL 数组类型概述 PostgreSQL 支持一维或多维数组作为数据存储的一种方式。这种特性允许在一个单独的表列中保存多个相同类型的值,从而简化某些复杂结构的数据管理[^1]。 #### 创建带有数组类型的表格 定义包含数组字段的表时,在类型后面加上方括号 `[]` 来表示该列为数组形式: ```sql CREATE TABLE students ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, courses TEXT[], -- 存储课程列表 grades INTEGER[] -- 成绩记录可以是一个整数数组 ); ``` #### 插入含有数组的数据 向具有数组属性的表内添加新纪录可以通过直接指定具体的数值来完成: ```sql INSERT INTO students (name, courses, grades) VALUES ('Alice', ARRAY['Math','Physics'], '{90,85}'); ``` 这里使用了两种不同的语法风格:一种是通过 `ARRAY` 构造器;另一种则是简单的花括号 `{}` 表达式[^2]。 #### 查询与过滤基于数组的内容 当需要检索特定条件下的记录时,可运用标准 SQL 的比较运算符以及专门针对数组设计的操作符来进行筛选: ```sql SELECT * FROM students WHERE 'Chemistry' = ANY(courses); -- 查找选修化学课的学生 ``` 上述命令会返回所有其 `courses` 列中含有 `'Chemistry'` 这门科目的学生信息。 #### 处理单个元素或子集 对于更复杂的场景,比如获取某个位置上的具体项或是截取部分序列,则需要用到索引和切片功能: ```sql SELECT courses[1], grades[2:3] FROM students; -- 获取第一个课程名及成绩中的第二到第三个分数 ``` 此语句展示了如何访问单一成员(即第一个人所学的第一门科目),同时也示范了怎样提取连续区间的片段(例如第二个至第三个人的成绩区间)。 #### 展开数组成多行显示 有时希望把每一个数组组件都独立呈现出来而不是作为一个整体展示给用户,这时就可以借助内置函数 `unnest()` 实现这一目标: ```sql SELECT unnest(grades) AS single_grade FROM students; ``` 这段代码将会把每条学生的各科成绩拆分成单独的一行输出[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值