相关疑难解决方法(0)

成对数组和聚合函数?

我有一个数组作为一列的表,我想将数组元素加在一起:

> create table regres(a int[] not null);
> insert into regres values ('{1,2,3}'), ('{9, 12, 13}');
> select * from regres;
     a
-----------
 {1,2,3}
 {9,12,13}
Run Code Online (Sandbox Code Playgroud)

我希望结果如下:

{10, 14, 16}
Run Code Online (Sandbox Code Playgroud)

那就是:{1 + 9, 2 + 12, 3 + 13}.

这样的功能在某处已经存在吗?插入扩展看起来是一个很好的候选者,但这样的功能尚不存在.

预计数组的长度在24到31个元素之间,所有元素都是NOT NULL,并且数组本身也将是NOT NULL.所有元素都是基本的int.每个聚合将有两行以上.在查询中,所有数组都将具有相同数量的元素.不同的查询将具有不同数量的元素.

我的实现目标是:x86_64-unknown-linux-gnu上的PostgreSQL 9.1.13,由gcc编译(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3,64位

postgresql aggregate-functions

8
推荐指数
1
解决办法
3152
查看次数

规范化1维数组的数组下标,使它们从1开始

PostgreSQL可以在任何地方开始使用数组下标.
考虑这个创建一个包含3个元素的数组的示例,其中包含5到7的下标:

SELECT ('[5:7]={1,2,3}'::int[]);
Run Code Online (Sandbox Code Playgroud)

返回:

[5:7]={1,2,3}
Run Code Online (Sandbox Code Playgroud)

例如,你得到第一个元素的含义

SELECT ('[5:7]={1,2,3}'::int[])[5];
Run Code Online (Sandbox Code Playgroud)

我想规范化 任何给定的1维数组以从数组下标1开始.
我能想到的最好的:

SELECT ('[5:7]={1,2,3}'::int[])[array_lower('[5:7]={1,2,3}'::int[], 1):array_upper('[5:7]={1,2,3}'::int[], 1)]
Run Code Online (Sandbox Code Playgroud)

或者,同样,更容易阅读:

WITH x(a) AS (
    SELECT '[5:7]={1,2,3}'::int[]
    )
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM   x
Run Code Online (Sandbox Code Playgroud)

你知道更简单/更快或更优雅的方式吗?


基准

为了测试性能,我提出了这个快速基准测试.
表有100k行,随机长度在1和11之间的简单整数数组:

CREATE TEMP TABLE t (a int[]);
INSERT INTO t -- now with actually varying subscripts
SELECT ('[' || g%10 || ':' || 2*(g%10) || ']={1'
            || repeat(','||g::text, g%10) || '}')::int[]
FROM   generate_series(1,100000) g;

EXPLAIN ANALYZE
SELECT 
       substring(a::text, '{.*$')::int[]       -- Total runtime: 949.304 …
Run Code Online (Sandbox Code Playgroud)

arrays postgresql performance

7
推荐指数
2
解决办法
1242
查看次数

在Postgres 9.4中查找JSON数组中的最后一项

我们有一个遗留系统,试图跟踪特定文档保存的所有数据版本.我们最初将JSON作为字符串存储在一些旧版本的Postgres中,但最近我们升级到Postgres 9.3并且我们开始使用JSON列类型.

我们有一个名为"versions"的列,它有一个数组,每个保存的特定文档版本都存储在数组中,所以这样的查询:

SELECT _data_as_json FROM measurements WHERE id = 3307551
Run Code Online (Sandbox Code Playgroud)

像这样返回JSON:

 {"reports": {}, "versions": [
 {"timestamp": "2014-04-28T19:12:31.567415", "user": 11327, "legacy": {}, "vd_version": 1}, 
 {"timestamp": "2014-05-12T18:03:24.417029", "user": 11331, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-05-12T21:52:50.045758", "user": 10373, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-05-14T23:34:37.797822", "user": 10380, "legacy": {"lengthmoment": {"moment": {"size": 130}, "length": {"in": 64.0}}, "comments": "", "custom": null}, "vd_version": 1}, 
 {"timestamp": "2014-07-16T14:56:38.667363", …
Run Code Online (Sandbox Code Playgroud)

postgresql json postgresql-9.3

7
推荐指数
1
解决办法
4373
查看次数

将字符串拆分为字符 SQL

如何在 PostgreSQL 中按字符分割字符串并在每个字符后添加新行

例如

num  desc
 1    Hello
 2    Bye

num  desc
 1    H
      e
      l
      l
      o

 2    B
      y 
      e
Run Code Online (Sandbox Code Playgroud)

postgresql

6
推荐指数
1
解决办法
8266
查看次数

子查询中的动态字段名称?

我有一个类似于以下的表:

CREATE TABLE stats (
  name character varying(15),
  q001001 numeric(9,0),
  q001002 numeric(9,0),
  q001003 numeric(9,0),
  q001004 numeric(9,0),
  q001005 numeric(9,0)
)
Run Code Online (Sandbox Code Playgroud)

我需要在这个表中查询各个字段的总和,如下所示:

SELECT sum(q001001) as total001,
       sum(q001002) as total002,
       sum(q001005) as total005,
FROM stats;
Run Code Online (Sandbox Code Playgroud)

这会产生一行数据和三列数据.
但是,出于报告目的,我需要以相反的方式列出结果.我需要三行和一列(好吧,实际上是两个,第一个是总和的字段),如下所示:

FieldName | SUM
----------+-------
q001001   |  12345
q001002   |  5432
q001005   |  986
Run Code Online (Sandbox Code Playgroud)

我想使用这样的一些SQL,其中field_name(来自stats表中字段名称的查找表)用于子查询:

select l.field_name, (select sum(l.field_name) from stats)
from stats_field_names_lookup as l
where l.field_name in ('Q001001', 'Q001002', 'Q001005');
Run Code Online (Sandbox Code Playgroud)

这里的想法是,sum(l.field_name)将替换为相关的实际字段名称,对于WHERE子句中的每个名称,然后进行评估以提供正确的求和结果值.但是,这会因以下错误而失败:

函数和(字符变化)不存在

因为值有文字/字符.如何将该字符值转换为要正确计算的未加引号的字符串?

这个SQL有效.但是,当然,每个都给出相同的和值field_name,因为它q001001在这里是硬编码的.

select l.field_name, …
Run Code Online (Sandbox Code Playgroud)

sql postgresql unpivot dynamic-sql aggregate-functions

6
推荐指数
1
解决办法
660
查看次数

PostgreSQL中的并行unfst()和排序顺序

我明白使用

SELECT unnest(ARRAY[5,3,9]) as id
Run Code Online (Sandbox Code Playgroud)

如果没有ORDER BY子句,则不保证结果集的顺序.我可以得到:

id
--
3
5
9
Run Code Online (Sandbox Code Playgroud)

但是以下请求呢:

SELECT
  unnest(ARRAY[5,3,9]) as id,
  unnest(ARRAY(select generate_series(1, array_length(ARRAY[5,3,9], 1)))) as idx
ORDER BY idx ASC
Run Code Online (Sandbox Code Playgroud)

是否保证2个unnest()调用(具有相同的长度)将并行展开,并且索引idx确实匹配数组中项目的位置?

我正在使用PostgreSQL 9.3.3.

sql postgresql unnest postgresql-9.3 set-returning-functions

6
推荐指数
1
解决办法
3839
查看次数

使用regexp_split_to_table时出错(Amazon Redshift)

我有同样的问题:
在Postgresql中拆分逗号分隔的字段并在所有结果表上执行UNION ALL
只是我的'fruits'列由'|'分隔.当我尝试:

SELECT 
    yourTable.ID, 
    regexp_split_to_table(yourTable.fruits, E'|') AS split_fruits
FROM yourTable
Run Code Online (Sandbox Code Playgroud)

我得到以下内容:

ERROR: type "e" does not exist
Run Code Online (Sandbox Code Playgroud)

Q1.怎么E办?我看到一些E不使用的例子.官方文档没有在他们的"快速棕色狐狸......"中解释它.

Q2.我该如何使用'|' 作为我查询的分隔符?

编辑:我正在使用PostgreSQL 8.0.2.unfst()和regexp_split_to_table()都不受支持.

postgresql amazon-redshift set-returning-functions

6
推荐指数
1
解决办法
3068
查看次数

如何使用postgreSQL访问数组内部索引?

这是我(也许通常适合你)的非优化解决方案:

使用非优化内部函数的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()功能提供了对"内部行计数器"的直接访问,但它是关于行,而不是关于数组,不幸的是性能更差.

arrays postgresql indexing

5
推荐指数
1
解决办法
3369
查看次数

单个选择列表中的SQL多个UNNEST

我正在实现一个Query系统.我实现了不需要的功能.现在用户询问在单个select语句中使用多个unfst.我使用PostgreSQL作为指南,因为大多数用户在我们的查询系统之前使用它.

PostgreSQL有这样奇怪的行为:

postgres=# select unnest(array[1,2]), unnest(array[1,2]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
(2 rows)

postgres=# select unnest(array[1,2]), unnest(array[1,2,3]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
      1 |      3
      2 |      1
      1 |      2
      2 |      3
(6 rows)
Run Code Online (Sandbox Code Playgroud)

我的实现总是生成笛卡尔积.我想知道,这背后的正确逻辑是什么?PostgreSQL正在做正确的事还是只是一个bug?我没有在ANSI文档或PostgreSQL文档中找到明确的描述.

sql postgresql unnest set-returning-functions

5
推荐指数
1
解决办法
1万
查看次数

如何在 PostgreSQL 9.4+ 中将简单的 json(b) int 数组转换为整数[]

我有一个来自 json 对象的数组:[1, 9, 12]

由于它使用方括号表示法,因为它是直接从 json 对象获取的,所以我无法将其转换为,::integer[]当我尝试使用时,array_agg(jsonb_array_elements(simpleintarray))我收到一条错误消息,说我需要按 id 进行分组,但由于数组不是对象(键/值) )对,但只是简单的整数,我不知道如何以相当有效的方式实现这一点。

从 json 返回上述简单 int 数组的查询是:

SELECT node.*, elem->'permissions' AS group_node_permissions
    FROM node
    LEFT OUTER JOIN
    jsonb_array_elements(my_user_group.node_permissions) elem
    ON elem->>'id' = node.id::text
    ORDER BY node.id
Run Code Online (Sandbox Code Playgroud)

elem->'permissions'理想情况下应该以 Postgres 数组的形式返回{},以便我稍后可以在其上使用该ANY(intarray)函数。

我想避免做多余的低效解决方法,例如用大括号替换方括号,然后转换elem->'permissions'->>整数数组,将其转换为字符串,尽管这可能会起作用。

在伪代码中,我真正需要的是能够得到相同的结果:

SELECT node.*, elem->'permissions'**::integer[]** AS group_node_permissions,

...但是当然由于json 数组与 PostgreSQL 数组格式之间的[]差异{},这会导致错误。

这是我当前的(非常丑陋的解决方案,但有效):

SELECT node.*, replace(replace(elem->>'permissions', '[', '{'),']','}')::integer[] AS group_node_permissions
Run Code Online (Sandbox Code Playgroud)

它将原始的 (jsonb) 转换为(integer[])[1, 9, …

sql arrays postgresql json types

5
推荐指数
1
解决办法
9002
查看次数