Vector arithmetic for arrays in postgres
Postgres does not have a concept of "number arrays" that support such arithmetic. However, it is easy enough to implement with the array primitives. For example:
select t.*,
(select array_agg(e.el1 * e.el2)
from unnest(t.ar1, t.ar2) e(el1, el2)
) ar
from (select array[1,2,3] as ar1, array[4,5,6] as ar2) t;
The unnest()
"unzips" the two arrays in element order. The array agg then "rezips" them based on the mathematical operation you want.
Actually, Postgres does preserve the ordering of the array with the subquery. But if you want to be explicit, use with ordinality
:
select t.*,
(select array_agg(e.el1 * e.el2 order by n)
from unnest(t.ar1, t.ar2) with ordinality e(el1, el2, n)
) ar
from (select array[1, 2, 3] as ar1, array[4, 5, 6] as ar2) t
Element wise array addition in PostgreSQL
You could use unnest with ordinality:
SELECT time, array_agg(elem order by nr)
FROM (SELECT time, nr, SUM(elem) AS elem
FROM tab,unnest(col) WITH ORDINALITY a(elem, nr)
GROUP BY time,nr) s
GROUP BY time;
DBFiddle Demo
Output:
┌──────┬──────────────────┐
│ time │ array_agg │
├──────┼──────────────────┤
│ 1 │ {4,6,5,6} │
│ 2 │ {15,9,10} │
│ 3 │ {11,12,13,14,15} │
└──────┴──────────────────┘
Postgres: on conflict, summing two vectrors(arrays)
There are two problems with the expression:
array_agg(unnest(test.counters) + unnest([2,0,2,1]))
- there is no
+
operator for arrays, - you cannot use set-valued expressions as an argument in an aggregate function.
You need to unnest both arrays in a single unnest()
call placed in the from clause:
insert into test (name, counters)
values ('Joe', array[2,0,2,1])
on conflict (name) do
update set
counters = (
select array_agg(e1 + e2)
from unnest(test.counters, excluded.counters) as u(e1, e2)
)
Also pay attention to the correct data syntax in values
and the use of a special record excluded
(find the relevant information in the documentation.)
Test it in db<>fiddle.
PostgreSQL adding two integer Arrays
I don't think there is such a function.
In order to achieve your goal (in SQL) you'd have to unnest the arrays, then add the corresponding elements and aggregate the results back to array.
SELECT
array_agg(
COALESCE(h1.val, 0)+COALESCE(h2.val, 0)
ORDER BY COALESCE(h1.row_number, h2.row_number)
) as result
FROM
(SELECT ROW_NUMBER() over (), val FROM unnest('{3,5,1,5}'::int[]) as val) as h1
FULL JOIN (SELECT ROW_NUMBER() over (), val FROM unnest('{2,2,2}'::int[]) as val) as h2 ON h1.row_number=h2.row_number
I'm using ROW_NUMBER window function to get the array element number.
FULL JOIN is required because the arrays may be of different length. It is also the reason why COALESCE is required when adding the elements.
Thanks to @a_horse_with_no_name the query may be rewritten using ordinality without relying on row_number() function:
SELECT
array_agg(
COALESCE(h1.val, 0)+COALESCE(h2.val, 0)
ORDER BY COALESCE(h1.no, h2.no)
) as result
FROM
unnest('{3,5,1,5}'::int[]) WITH ORDINALITY as h1(val, no)
FULL JOIN unnest('{2,2,2}'::int[]) WITH ORDINALITY as h2(val, no) ON h1.no=h2.no
Adding value to Postgres integer array
Use array_append
function to append an element at the end of an array:
UPDATE table1
SET integer_array = array_append(integer_array, 5);
5 is a value of choice, it's of an integer datatype in your case. You probably need some WHERE
clause as well not to update the entire table.
Try below to see how it works:
SELECT ARRAY[1,2], array_append(ARRAY[1,2],3);
Result:
array | array_append
-------+--------------
{1,2} | {1,2,3}
Select sum of an array column in PostgreSQL
SELECT id, (SELECT SUM(s) FROM UNNEST(monthly_usage) s) as total_usage from users;
Apply function to every element of an array in a SELECT statement
you can use internal "undocumented" function pg_catalog.pg_get_function_arguments(p.oid).
postgres=# SELECT pg_catalog.pg_get_function_arguments('fufu'::regproc);
pg_get_function_arguments
---------------------------
a integer, b integer
(1 row)
Now, there are no build "map" function. So unnest, array_agg is only one possible. You can simplify life with own custom function:
CREATE OR REPLACE FUNCTION format_types(oid[])
RETURNS text[] AS $$
SELECT ARRAY(SELECT format_type(unnest($1), null))
$$ LANGUAGE sql IMMUTABLE;
and result
postgres=# SELECT format_types('{21,22,23}');
format_types
-------------------------------
{smallint,int2vector,integer}
(1 row)
Then your query should to be:
SELECT proname, format_types(proallargtypes)
FROM pg_proc
WHERE pronamespace = 2200 AND proallargtypes;
But result will not be expected probably, because proallargtypes field is not empty only when OUT parameters are used. It is empty usually. You should to look to proargtypes field, but it is a oidvector type - so you should to transform to oid[] first.
postgres=# SELECT proname, format_types(string_to_array(proargtypes::text,' ')::oid[])
FROM pg_proc
WHERE pronamespace = 2200
LIMIT 10;
proname | format_types
------------------------------+----------------------------------------------------
quantile_append_double | {internal,"double precision","double precision"}
quantile_append_double_array | {internal,"double precision","double precision[]"}
quantile_double | {internal}
quantile_double_array | {internal}
quantile | {"double precision","double precision"}
quantile | {"double precision","double precision[]"}
quantile_cont_double | {internal}
quantile_cont_double_array | {internal}
quantile_cont | {"double precision","double precision"}
quantile_cont | {"double precision","double precision[]"}
(10 rows)
Related Topics
How to Remove Duplicates from Table Using SQL Query
Search All Databases for Value
How to Find Values in All Caps in SQL Server
Left Inner Join VS. Left Outer Join - Why Does the Outer Take Longer
How to Select Rows Where a Column Value Starts with a Certain String
How to Reuse a Common Table Expression
How to Make Comment Reply Query in MySQL
Using Bcp Utility to Export SQL Queries to a Text File
Select Records in on Table Based on Conditions from Another Table
Deferrable Check Constraint in Postgresql
How to Expand a "Condensed" Postgresql Row into Separate Columns
Logging Erroneous Queries Only on SQL Server
Help with Writing a SQL Query for Nested Sets
Filter Duplicate Rows Based on a Field
Oracle: Can You Assign an Alias to the from Clause