并行取消嵌套多个数组
Unnest multiple arrays in parallel
我的最后一个问题 Passing an array to stored to postgres 有点不清楚。现在,澄清我的目标:
我想创建一个将接受两个输入参数的 Postgres 存储过程。一个将是一些 金额 的列表,例如 (100, 40.5, 76)
,另一个将是一些 发票 [=2= 的列表].之后我想使用这两个数字和字符列表并对它们做一些事情。例如,我想从这个数字数组中取出每个金额并将其分配给相应的发票。
Oracle 中类似的东西如下所示:
SOME_PACKAGE.SOME_PROCEDURE (
789,
SYSDATE,
SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'),
NUMBER_TABLE (100,40.5,76),
'EUR',
1,
P_CODE,
P_MESSAGE);
当然,SIMPLEARRAYTYPE
和NUMBER_TABLE
这两个类型在DB中定义的比较早
数组是通过将 []
添加到基本数据类型来声明的。您可以像声明常规参数一样将它们声明为参数:
以下函数接受整数数组和字符串数组,并将 return 一些虚拟文本:
create function array_demo(p_data integer[], p_invoices text[])
returns text
as
$$
select p_data[1] || ' => ' || p_invoices[1];
$$
language sql;
select array_demo(array[1,2,3], array['one', 'two', 'three']);
SQLFiddle 演示:http://sqlfiddle.com/#!15/fdb8d/1
您会喜欢 Postgres 9.4的这个新特性:
<b>unnest(anyarray, anyarray [, ...])</b>
unnest()
具有令人期待的(至少是我)并行取消嵌套多个数组的能力 干净地。 The manual:
expand multiple arrays (possibly of different types) to a set of rows. This is only allowed in the FROM clause;
这是新 ROWS FROM
feature 的特殊实现。
您的函数现在可以是:
CREATE OR REPLACE FUNCTION multi_unnest(_some_id int
, _amounts numeric[]
, _invoices text[])
RETURNS TABLE (some_id int, amount numeric, invoice text) AS
$func$
SELECT _some_id, u.* FROM <b>unnest(_amounts, _invoices)</b> u;
$func$ LANGUAGE sql;
通话:
SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[]
, '{01-2222-05,01-3333-04,01-4444-08}'::text[]);
当然简单形式可以换成plain SQL(无附加功能):
SELECT 123 AS some_id, *
FROM unnest('{100, 40.5, 76}'::numeric[]
, '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);
在早期版本(Postgres 9.3-)中,您可以使用不太优雅和不太安全的形式:
SELECT 123 AS some_id
, unnest('{100, 40.5, 76}'::numeric[]) AS amount
, unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;
旧 shorthand 形式的注意事项:除了在 SELECT
列表中具有设置返回函数的非标准之外,返回的行数将是每个数组的最小公倍数元素的数量(对于不相等的数字有令人惊讶的结果)。这些相关答案中的详细信息:
- Parallel unnest() and sort order in PostgreSQL
- Is there something like a zip() function in PostgreSQL that combines two arrays?
这种行为终于被 Postgres 10 净化了。 SELECT
列表中的多个集合返回函数现在以“锁步”方式生成行。参见:
我的最后一个问题 Passing an array to stored to postgres 有点不清楚。现在,澄清我的目标:
我想创建一个将接受两个输入参数的 Postgres 存储过程。一个将是一些 金额 的列表,例如 (100, 40.5, 76)
,另一个将是一些 发票 [=2= 的列表].之后我想使用这两个数字和字符列表并对它们做一些事情。例如,我想从这个数字数组中取出每个金额并将其分配给相应的发票。
Oracle 中类似的东西如下所示:
SOME_PACKAGE.SOME_PROCEDURE (
789,
SYSDATE,
SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'),
NUMBER_TABLE (100,40.5,76),
'EUR',
1,
P_CODE,
P_MESSAGE);
当然,SIMPLEARRAYTYPE
和NUMBER_TABLE
这两个类型在DB中定义的比较早
数组是通过将 []
添加到基本数据类型来声明的。您可以像声明常规参数一样将它们声明为参数:
以下函数接受整数数组和字符串数组,并将 return 一些虚拟文本:
create function array_demo(p_data integer[], p_invoices text[])
returns text
as
$$
select p_data[1] || ' => ' || p_invoices[1];
$$
language sql;
select array_demo(array[1,2,3], array['one', 'two', 'three']);
SQLFiddle 演示:http://sqlfiddle.com/#!15/fdb8d/1
您会喜欢 Postgres 9.4的这个新特性:
<b>unnest(anyarray, anyarray [, ...])</b>
unnest()
具有令人期待的(至少是我)并行取消嵌套多个数组的能力 干净地。 The manual:
expand multiple arrays (possibly of different types) to a set of rows. This is only allowed in the FROM clause;
这是新 ROWS FROM
feature 的特殊实现。
您的函数现在可以是:
CREATE OR REPLACE FUNCTION multi_unnest(_some_id int
, _amounts numeric[]
, _invoices text[])
RETURNS TABLE (some_id int, amount numeric, invoice text) AS
$func$
SELECT _some_id, u.* FROM <b>unnest(_amounts, _invoices)</b> u;
$func$ LANGUAGE sql;
通话:
SELECT * FROM multi_unnest(123, '{100, 40.5, 76}'::numeric[]
, '{01-2222-05,01-3333-04,01-4444-08}'::text[]);
当然简单形式可以换成plain SQL(无附加功能):
SELECT 123 AS some_id, *
FROM unnest('{100, 40.5, 76}'::numeric[]
, '{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS u(amount, invoice);
在早期版本(Postgres 9.3-)中,您可以使用不太优雅和不太安全的形式:
SELECT 123 AS some_id
, unnest('{100, 40.5, 76}'::numeric[]) AS amount
, unnest('{01-2222-05,01-3333-04,01-4444-08}'::text[]) AS invoice;
旧 shorthand 形式的注意事项:除了在 SELECT
列表中具有设置返回函数的非标准之外,返回的行数将是每个数组的最小公倍数元素的数量(对于不相等的数字有令人惊讶的结果)。这些相关答案中的详细信息:
- Parallel unnest() and sort order in PostgreSQL
- Is there something like a zip() function in PostgreSQL that combines two arrays?
这种行为终于被 Postgres 10 净化了。 SELECT
列表中的多个集合返回函数现在以“锁步”方式生成行。参见: