PostgreSQL 數組類型
PostgreSQL 支持表的字段使用定長或可變長度的一維或多維數組,數組的類型可以是任何數據庫內建的類型、用戶自定義的類型、枚舉類型,
以及組合類型。但目前還不支持 domain 類型。
數組類型的定義就是通過在數組元素類型名后面附加中括號 [] 來實現的,中括號中可以給一個長度數字,也可以不給,
定義指定多維數組的維度也是沒有意義的,數組的維度是根據實際插入的數據來確定的,如下兩個語句意義是一樣的:
CREATE TABLE test1 (id int, col1 int[], col2 int[10], col3 text[][]); CREATE TABLE test2 (id int, col1 int[10], col2 int[], col3 text[]);
如何輸入數組值
可以使用 ARRAY 構造器語法輸入數據,一個數組構造器是一個表達式,它從自身的成員上構造一個數組值。
一個簡單的數組構造器由關鍵字 ARRAY、[、一個或多個表示數組元素值的表達式(用逗號分隔)、] 組成
INSERT INTO test values(1, ARRAY['os', 'dba']); INSERT INTO test values(1, ARRAY['os"dba', '123"456']); INSERT INTO test values(1, ARRAY['os''dba', '123''456']); // 多維數組,在向多維數組插入值時,各個維度的元素個數必須相同,否則會報錯 INSERT INTO test values(1, ARRAY[['os', 'dba'],['dba', 'os']]);
訪問數組
默認情況下,數組的下標是從 1 開始的,但也可以指定下標的開始值,如下:
CREATE TABLE test02 (id int[]); INSERT INTO test02 values('[2:4] = {1, 2, 3}'); SELECT id[2], id[3], id[4] FROM test02;
指定上下標的格式為:
'[下標:上標] = [元素值1,元素值2,元素值3,...]'
可以使用數組的切片,如下所示:
SELECT id, col[1:2] FROM test02;
數組的操作符
數組類型支持一些集合關系的操作符,如下所示:
@> 包含
ARRAY[1, 2, 3] @> ARRAY[1, 2]
結果:t
ARRAY[1, 2, 3] @> ARRAY[1, 4]
結果:f
ARRAY[1, 2, 3] @> ARRAY[2, 1]
結果:t
ARRAY[[1, 2, 3]] @> ARRAY[[1, 2], [2, 3]]
結果:t
<@ 被包含於
ARRAY[1, 2] <@ ARRAY[1, 2, 3]
結果:t
ARRAY[2, 1] <@ ARRAY[1, 2, 3]
結果:t
ARRAY[1, 4] <@ ARRAY[1, 2, 3]
結果:t
ARRAY[[1, 2], [2, 4]] <@ ARRAY[1, 2, 3]
結果:f
&& 重疊,是否有共同元素
ARRAY[1, 2, 3] && ARRAY[3, 4]
結果:t
ARRAY[[1, 2], [3, 4]] && ARRAY[4, 5]
結果:t
ARRAY[1, 2] && ARRAY[3, 4]
結果:f
做集合比較時,不管數組中的元素在哪一維,都可以把它們當作集合中的一個元素,而與數組的維度沒有關系。
連接操作符 “||”
同維度的數組與數組連接
ARRAY[1, 2] || ARRAY[3, 4]
結果:{1,2,3,4}
ARRAY[1, 2] || ARRAY[2, 3]
結果:{1,2,2,3}
不同維度的數組與數組連接
ARRAY[1, 2] || ARRAY[[3, 4], [5, 6]]
結果:{{1, 2}, {3, 4}, {5, 6}}
元素與數組之間的連接
1 || ARRAY[2, 3]
結果:{1, 2, 3}
ARRAY[2, 3] || 1
結果:{2, 3, 1}
1 || ARRAY[[2, 3]]
結果:報錯
數組的函數
array_cat(anyarray, anyarray)
連接兩個數組,返回新數組
示例:array_cat(ARRAY[1, 2], ARRAY[3, 4]) 結果:{1, 2, 3, 4}
array_cat(ARRAY[[1, 2]], ARRAY[3, 4]) 結果:{{1, 2}, {3, 4}}
array_cat(ARRAY[[1, 2]], ARRAY[[3, 4]]) 結果:{{1, 2}, {3, 4}}
array_ndims(anyarray)
返回數組的維度,返回值類型為 int
示例:array_ndims(ARRAY[1, 2, 3]) 結果:1
array_ndims(ARRAY[[1, 2, 3]]) 結果:2
array_ndims(ARRAY[[1, 2, 3], [4, 5, 6]]) 結果:2
array_ndims(ARRAY[[[1, 2, 3]]]) 結果:3
array_length(anyarray, int)
返回數組指定維度的長度,維度數是有由第二個參數指定的
示例: array_length(ARRAY[1, 2, 4], 1) 結果:3
array_length(ARRAY[[1, 2], [3, 4], [5, 6]], 1) 結果:3
array_length(ARRAY[[1, 2], [3, 4], [5, 6]], 2) 結果:2
array_lower(anyarray, int)
返回數組的下標
array_upperer(anyarray, int)
返回數組的上標
array_prepend(anyelement, anyarray)
在數組的開頭插入一個元素
示例: array_prepend(7, ARRAY[8, 9]) 結果:{7, 8, 9}
array_remove(anyarray, anyelement)
移除數組中為指定值的元素,只支持一維數組
示例: array_remove(ARRAY[1, 2, 3], 2) 結果: {1, 3}
array_remove(ARRAY[1, 2, 3, 2, 1, 2], 2) 結果: {1, 3. 1}
array_replace(anyarray, anyelement, anyelement)
把數組中等於指定值元素的值用另一個指定值替代
示例: array_replace(ARRAY[1, 4, 3], 4, 2) 結果:{1,2,3}
array_to_string(anyarray, text)
使用指定的分隔符(第二個參數) 將數組元素連接為字符串
示例: array_to_string(ARRAY[1,2,3], ',') 結果:'1,2,3'
string_to_array(text, text)
用指定的分隔符分隔的字符串轉成數組
示例:string_to_array('1,2,3', ',') 結果:{1, 2, 3}
unnest(anyarray)
把數組變成多行返回
array_agg(字段)
聚合函數
轉發請著名出處:https://www.cnblogs.com/ryanzheng/p/9610182.html
--原始 -- wf."WorkflowDefinition"."StartEvents" :"18,3" --更新后 -- wf."WorkflowDefinition"."StartEvents" :"3" do $_$ declare pwfname varchar(50)= '****申請'; r_WorkflowDefinition record; array_StartEvents varchar[]; array_FinishEvents varchar[]; emailEvent varchar[]= array['3']; begin select into r_WorkflowDefinition * from wf."WorkflowDefinition" where "Name" = pwfname limit 1; if(r_WorkflowDefinition."WorkflowId" is null) then raise notice 'warn: skip.no r_WorkflowDefinition can be found. Name:%',pwfname; else array_StartEvents = array_remove(string_to_array(r_WorkflowDefinition."StartEvents",',')::int[], 3); array_FinishEvents =array_remove(string_to_array(r_WorkflowDefinition."FinishEvents",',')::int[], 3); raise notice 'info: update r_WorkflowDefinition. Name:%, IsHumanFlow, from:% to:%; StartEvents, from:% to:%; FinishEvents, from:% to:%; original data:% ',pwfname, r_WorkflowDefinition."IsHumanFlow",false, r_WorkflowDefinition."StartEvents",array_to_string(array_StartEvents, ','), r_WorkflowDefinition."FinishEvents",array_to_string(array_FinishEvents, ','), to_json(r_WorkflowDefinition); UPDATE wf."WorkflowDefinition" SET "IsHumanFlow"=false, "StartEvents"=array_to_string(array_StartEvents, ','), "FinishEvents"=array_to_string(array_FinishEvents, ',') WHERE "WorkflowId" = r_WorkflowDefinition."WorkflowId"; end if; end $_$;
SELECT string_to_array('xx~^~yy~^~zz', '~^~'); --{xx,yy,zz} SELECT string_to_array('18,3,1',',')::int[]; --{18,3,1} SELECT string_to_array('18,3,1',','); --{18,3,1} select array_remove(string_to_array('18,3,1',',')::int[], 3) ; --{18,1} SELECT array_remove(array ['18','3'], '3'); --{18} select array_remove(ARRAY[1, 2, 3], 2) ; --{1,3} --是否存在交集 select string_to_array('18,3,1',',')::int[] && string_to_array('2,3',',')::int[]; --true select string_to_array('18,3,1',',')::int[] && string_to_array('2,9',',')::int[]; --false --是否包含 select ARRAY[1, 2, 3] @> ARRAY[1, 2] --true SELECT ARRAY['18','3'],string_to_array('18,3',','); --{18,3} {18,3}
官方文檔:
https://www.postgresql.org/docs/9.1/arrays.html
https://www.w3resource.com/PostgreSQL/postgresql_string_to_array-function.php
---array --命名表 create table arraytest(inttype int,intshuzu int[],varshuzu varchar(32)[][]); --輸入array值 INSERT INTO test values(1, ARRAY['os','dba', '123','456']); --多維數組,在向多維數組插入值時,各個維度的元素個數必須相同,否則會報錯 INSERT INTO test values(1, ARRAY[['os', 'dba'],['dba', 'os']]); --取數組中的一個元素 (array_agg(eff_date))[1] 取數組的第一個元素(下標從1開始) --array_to_string(anyarray, text) 使用指定的分隔符(第二個參數) 將數組元素連接為字符串 array_to_string(ARRAY[1,2,3], ',') 結果:'1,2,3' --string_to_array(text, text) 用指定的分隔符分隔的字符串轉成數組 string_to_array('1,2,3', ',') 結果:{1, 2, 3} --unnest(anyarray) 把數組變成多行返回 select * from book; id | name | tag ----+------+---------- 1 | java | aa,bb,cc 2 | C++ | dd,ee 則 select name,unnest(string_to_array(tag,',')) from book; name | unnest ------+-------- java | aa java | bb java | cc C++ | dd C++ | ee --聚合函數 把多行值合並成一行 array_agg(exp, ',') --把表達式變成數組 string_agg(exp, ',') --把表達式變成一個字符串 --array_length(anyarray, int) 返回數組指定維度的長度,維度數是有由第二個參數指定的 array_length(ARRAY[1, 2, 4], 1) 結果:3 array_length(ARRAY[[1, 2], [3, 4], [5, 6]], 1) 結果:3 array_length(ARRAY[[1, 2], [3, 4], [5, 6]], 2) 結果:2 --同維度的數組與數組連接 ARRAY[1, 2] || ARRAY[3, 4] --結果:{1,2,3,4} --@> 包含 ARRAY[1, 2, 3] @> ARRAY[1, 2] --結果:t ARRAY[1, 2, 3] @> ARRAY[1, 4] --結果:f --數組包含某元素否 select * from mytable where 'Journal'=ANY(pub_types); 即語法是<value> = ANY ( <array> )。還要注意postresql中的字符串文字是用單引號寫的。 --array_remove(anyarray, anyelement) 移除數組中為指定值的元素,只支持一維數組 array_remove(ARRAY[1, 2, 3], 2) --結果: {1, 3} array_remove(ARRAY[1, 2, 3, 2, 1, 2], 2) --結果: {1, 3. 1} --array_replace(anyarray, anyelement, anyelement) 把數組中等於指定值元--素的值用另一個指定值替代 array_replace(ARRAY[1, 4, 3], 4, 2) --結果:{1,2,3}