当我有一个具有分隔值的列时,我可以使用该unnest()函数:
myTable
id | elements
---+------------
1 |ab,cd,efg,hi
2 |jk,lm,no,pq
3 |rstuv,wxyz
select id, unnest(string_to_array(elements, ',')) AS elem
from myTable
id | elem
---+-----
1 | ab
1 | cd
1 | efg
1 | hi
2 | jk
...
Run Code Online (Sandbox Code Playgroud)
我如何包含元素编号?即:
id | elem | nr
---+------+---
1 | ab | 1
1 | cd | 2
1 | efg | 3
1 | hi | 4
2 | jk | 1
...
Run Code Online (Sandbox Code Playgroud)
我想要源字符串中每个元素的原始位置.我试着窗口函数(row_number(), …
sql arrays postgresql window-functions set-returning-functions
我的最后一个问题将数组传递给存储到postgres有点不清楚.现在,澄清我的目标:
我想创建一个Postgres存储过程,它将接受两个输入参数.一个将是一些数量的列表,例如(100, 40.5, 76),另一个将是一些发票的 列表('01-2222-05','01-3333-04','01-4444-08').之后我想使用这两个数字和字符列表并对它们做一些事情.例如,我想从这一组数字中取出每个金额,并将其分配给相应的发票.
在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);
Run Code Online (Sandbox Code Playgroud)
当然,这两种类型SIMPLEARRAYTYPE,并NUMBER_TABLE出现在靠前的DB定义.
这是我(也许通常适合你)的非优化解决方案:
使用非优化内部函数的PG问题的解决方法:
CREATE FUNCTION unnest_with_idx(anyarray)
RETURNS TABLE(idx integer, val anyelement) AS
$$
SELECT generate_series(1,array_upper($1,1)) as idx, unnest($1) as val;
$$ LANGUAGE SQL IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)
测试:
SELECT idx,val from unnest_with_idx(array[1,20,3,5]) as t;
Run Code Online (Sandbox Code Playgroud)
但是,正如我所说,非优化.我不敢相信(!!)PostgreSQL没有数组的内部索引......?但在这种情况下,问题是如何直接访问这个GIN类内部计数器的指数?
注1:上面的解决方案和问题与" 如何通过数组的每个元素创建索引? "不同.也可以与" Can PostgreSQL索引数组列? "不同,因为该函数用于隔离数组,而不是用于数组字段的表索引.
NOTE2(在答案后编辑):"数组索引"(更常用的术语)或"数组下标"或"数组计数器"是我们可以在语义路径中使用的术语,用于将"内部计数器",累加器引用到下一个数组项目.我看到没有PostgreSQL命令提供对此计数器的直接访问.作为generate_series()函数,generate_subscripts()函数是序列生成器,并且性能(最好但是)接近相同.通过其他手工row_number()功能提供了对"内部行计数器"的直接访问,但它是关于行,而不是关于数组,不幸的是性能更差.
我试图通过两个set-returns函数得到一个"交叉连接",但在某些情况下我没有得到"交叉连接",请参阅示例
行为1:当设置的长度相同时,它会逐个匹配每个集合中的项目
postgres=# SELECT generate_series(1,3), generate_series(5,7) order by 1,2;
generate_series | generate_series
-----------------+-----------------
1 | 5
2 | 6
3 | 7
(3 rows)
行为2:当设置的长度不同时,它会"交叉连接"这些集合
postgres=# SELECT generate_series(1,2), generate_series(5,7) order by 1,2;
generate_series | generate_series
-----------------+-----------------
1 | 5
1 | 6
1 | 7
2 | 5
2 | 6
2 | 7
(6 rows)
我想我在这里不了解一些事情,有人可以解释一下这种行为吗?
编辑:另一个例子,比以前更奇怪
postgres=# SELECT generate_series(1,2) x, generate_series(1,4) y order by x,y; x | y ---+--- 1 | 1 1 | 3 …