]> git.8kb.co.uk Git - postgresql/pg_2d_arrays/commitdiff
Initial commit master
authorglyn <glyn@8kb.co.uk>
Mon, 15 Dec 2014 21:55:50 +0000 (21:55 +0000)
committerglyn <glyn@8kb.co.uk>
Mon, 15 Dec 2014 21:55:50 +0000 (21:55 +0000)
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
pg_array_agg_mult.sql [new file with mode: 0644]
pg_two_dimensional_unnest.plpgsql [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..ff37810
--- /dev/null
@@ -0,0 +1,2 @@
+.DS_Store
+Thumb.db
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..7d154d0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,31 @@
+2d_arrays
+==========
+
+Just a couple of functions and an aggregate for working with multidimensional (2 dimensional) arrays in PostgreSQL.
+
+Usage
+-----
+
+```sql
+TEST=# select unnest_element(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]],3);
+ unnest_element
+----------------
+              3
+              6
+(2 rows)
+
+TEST=# select unnest_first(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]]);
+ unnest_dimension
+------------------
+ {1,2,3}
+ {4,5,6}
+(2 rows)
+
+-- (Ref http://stackoverflow.com/questions/9832973/initial-array-in-function-to-aggregate-multi-dimensional-array)
+TEST=# SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) 
+       FROM (SELECT 1 AS a, 2 AS b UNION SELECT 2 AS a, 4 AS b) t;
+ array_agg_mult
+----------------
+ {{1,2},{2,4}}
+(1 row) 
+```
diff --git a/pg_array_agg_mult.sql b/pg_array_agg_mult.sql
new file mode 100644 (file)
index 0000000..66c8c54
--- /dev/null
@@ -0,0 +1,16 @@
+-- To aggregate rows into 2 dimensional arrays see the following custom aggregate by Erwin Brandstetter
+-- http://stackoverflow.com/questions/9832973/initial-array-in-function-to-aggregate-multi-dimensional-array
+
+CREATE AGGREGATE public.array_agg_mult (anyarray)  (
+    SFUNC     = array_cat
+   ,STYPE     = anyarray
+   ,INITCOND  = '{}'
+);
+
+-- E.g.
+-- TEST=# SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) 
+--        FROM (SELECT 1 AS a, 2 AS b UNION SELECT 2 AS a, 4 AS b) t;
+--  array_agg_mult
+-- ----------------
+--  {{1,2},{2,4}}
+-- (1 row)       
diff --git a/pg_two_dimensional_unnest.plpgsql b/pg_two_dimensional_unnest.plpgsql
new file mode 100644 (file)
index 0000000..747bc21
--- /dev/null
@@ -0,0 +1,56 @@
+-- 
+-- Glyn Astill 21/04/2012
+-- Functions to assist unnesting multidimensional arrays in PostgreSQL 9.0 and earlier
+--
+
+-- Some similar functions for Pg 9.1+ only can be found here
+-- https://wiki.postgresql.org/wiki/Unnest_multidimensional_array
+-- https://wiki.postgresql.org/wiki/Multidimensional_Array_Mapping
+
+
+-- Given a 2 dimensional array will unnest the element at the supplied
+-- index in the second dimension.
+-- Pg 8.0+
+CREATE OR REPLACE FUNCTION public.unnest_element(anyarray, integer)
+RETURNS SETOF anyelement
+AS $BODY$
+BEGIN
+       RETURN QUERY SELECT $1[i][$2]
+       FROM generate_series(array_lower($1,1), array_upper($1,1)) i;
+END;
+$BODY$
+LANGUAGE plpgsql IMMUTABLE;
+
+--
+
+-- Given a 2 dimensional array will unnest the first dimension
+-- returning the a set of one dimensional array.
+-- Pg 8.4+
+CREATE OR REPLACE FUNCTION public.unnest_first(anyarray)
+RETURNS SETOF anyarray
+AS $BODY$
+BEGIN
+       RETURN QUERY 
+       SELECT (SELECT array_agg($1[i][i2])
+               FROM generate_series(array_lower($1,2), array_upper($1,2)) i2)
+       FROM generate_series(array_lower($1,1), array_upper($1,1)) i;
+END;
+$BODY$
+LANGUAGE plpgsql IMMUTABLE;
+
+
+-- E.g.
+-- 
+-- TEST=# select unnest_element(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]],3);
+--  unnest_element
+-- ----------------
+--               3
+--               6
+-- (2 rows)
+-- 
+-- TEST=# select unnest_first(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]]);
+--  unnest_dimension
+-- ------------------
+--  {1,2,3}
+--  {4,5,6}
+-- (2 rows)