ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 概述 pgsql 指定对数组的操作 ## 数组操作符 |符号|说明|示例 |---|---|--| |anyarray @> anyarray → boolean|第一个数组是否包含第二个数组|ARRAY[1,4,3] @> ARRAY[3,1,3] → t| |anyarray <@ anyarray → boolean|第一个数组包含在第二个数组中么?|ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6] → t| | anyarray && anyarray → boolean | 是否有交集 | ARRAY[1,4,3] && ARRAY[2,1] → t| |anyarray || anyarray → anyarray | 连接两个数组|ARRAY[1,2,3] || ARRAY[4,5,6,7] → {1,2,3,4,5,6,7} | |anyelement || anyarray → anyarray | 元素追加到数组前| 3 || ARRAY[4,5,6] → {3,4,5,6}| | anyarray || anyelement → anyarray 元素追加到数组后 | ARRAY[4,5,6] || 7 → {4,5,6,7} | ## 数组类型 ### 声明数组 创建带数组的表 ``` CREATE TABLE sal_emp ( name text, pay_by_quarter integer[], schedule text[][] ); ``` 可指定长度 ``` CREATE TABLE tictactoe ( squares integer[3][3] ); ``` > 然而,当前的实现忽略任何提供的数组尺寸限制,即其行为与未指定长度的数组相同。 > 在`CREATE TABLE`中声明数组的尺寸或维度数仅仅只是文档而已,它并不影响运行时的行为 ### 插入数组 多维数组必须有相同的长度,否则会报错 ``` INSERT INTO sal_emp VALUES ('Bill', '{10000, 10000, 10000, 10000}', '{{"meeting", "lunch"}, {"training", "presentation"}}'); ``` 效果 ``` SELECT * FROM sal_emp; name | pay_by_quarter | schedule -------+---------------------------+------------------------------------------- Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}} Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}} ``` ### 访问数组 数组的索引从0 开始,如果小标超过实际大小,只返回空,不会抛异常 ```sql --查询不等于的值 SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2]; --查询某个数组值 SELECT pay_by_quarter[3] FROM sal_emp; -- 查询数组切片 SELECT pay_by_quarter[1:3] FROM sal_emp; SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR pay_by_quarter[2] = 10000 OR pay_by_quarter[3] = 10000 OR pay_by_quarter[4] = 10000; --or SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter); -- 查询都为1000的值 SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter); -- 拼接数组 SELECT ARRAY[1,2] || ARRAY[3,4]; -- 输出 ?column? ----------- {1,2,3,4} ``` ### 修改数组 ```sql -- 整体更新数组 UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}' WHERE name = 'Carol'; -- or UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000] WHERE name = 'Carol'; -- 更新个别数组 UPDATE sal_emp SET pay_by_quarter[4] = 15000 WHERE name = 'Bill'; -- 更新切片 UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}' WHERE name = 'Carol'; ``` ### 复合类型 ``` CREATE TYPE inventory_item AS ( name text, supplier_id integer, price numeric ); CREATE TABLE on_hand ( item inventory_item, count integer ); INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000); ``` 避免获取操作与 表字段一样,用括号进行区别 ``` SELECT item.name FROM on_hand WHERE item.price > 9.99; //改 SELECT (item).name FROM on_hand WHERE (item).price > 9.99; //ro SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99; ``` ### 相关函数 * `array_append`:向数组尾部添加元素; * `array_cat`:拼接两个数组; * `array_remove`:删除某个元素; * `array_replace`:替换某个元素; * `tags @> '{test}'`:是否包含某个元素; * `array_to_string`:数组以特定连接符连接并且以字符串形式返回; * `array_dims` 返回数组的维度 * `array_length` 返回数组的维度 ``` select tags,   //执行结果: {1,2,3,test}       array_append(tags, '9') as array_append, //执行结果: {1,2,3,test,9}       array_cat(tags, tags) as array_cat, //执行结果: {1,2,3,test,1,2,3,test}       array_remove(tags, 'test'), //执行结果: {1,2,3}       array_replace(tags, 'test', 'TEST'), //执行结果: {1,2,3,TEST}       tags @> '{test}', //执行结果: true       array_to_string(tags, ',') //执行结果: 1,2,3,TEST from t1 where id = 1; ``` ### 使用php pdo 处理数组 使用php 处理 pgsql 的数组,把数组转为 json,在通过php的json_decode 处理 ``` $stmt = $pdo->query("SELECT array_to_json(myarray) FROM mytable"); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); $myarray = json_decode($result[0]['array_to_json'], true); ```