标签: array

PostgreSQL:如何将多字串缩短为几个字?

我正在使用 PostgreSQL 9.5.6。我有空格分隔的多字串,我需要缩短说 3 个字?

我查看了文档,为了使用 substring() 函数,我需要知道要开始提取的字符的索引位置,但我正在使用的字符串长度不同。

我也看过 split_part() 并且只返回一个词。

我怎样才能得到类似的东西:

hello everyone out there somewhere
Run Code Online (Sandbox Code Playgroud)

缩短为

hello everyone out
Run Code Online (Sandbox Code Playgroud)

postgresql array string

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

使用复合类型的数组作为函数参数并访问它

Books在 Postgres 中创建了一个类型,它有 2 个numeric字段和 2 个varchar字段。我想将Books一个函数的数组发送到INSERT匹配表中的那些值。

这是我的类型:

CREATE TYPE Books AS (
V_Book_ID NUMERIC,
V_Row_Num NUMERIC,
V_Book_OWNER TEXT,
V_Book_OWNER_ID TEXT
);
Run Code Online (Sandbox Code Playgroud)

这是我的功能:

CREATE OR REPLACE FUNCTION Update_Table(row_book Books[]) RETURNS TEXT AS $$
DECLARE
   Status TEXT;
   I_Max integer := array_length(row_book, 1);
BEGIN
FOR I in 1..I_Max
  LOOP
   INSERT INTO books_table(Book_ID,
   Row_Num,
   Book_OWNER,
   Book_OWNER_ID)
   values
   (row_book[I].V_Book_ID,
   row_book[I].V_Row_Num,
   row_book[I].V_Book_OWNER,
   row_book[I].V_Book_OWNER_ID);
END LOOP;

   STATUS:='Saved';
exception when others then
   STATUS:='failure';
   RETURN STATUS;

END;
$$ …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql functions array composite-types

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

array_length 如果数组为空行为

请向我解释这种行为。

此 SQL 查找 ids (type is array::bigint) 为空的元素。

SELECT * FROM rises WHERE ids = '{}'
-- finds, e.g., 9 rows
Run Code Online (Sandbox Code Playgroud)

此 SQL 未找到任何行:

SELECT * FROM rises WHERE array_length(ids, 1) = 0
--finds always 0 rows
Run Code Online (Sandbox Code Playgroud)

但是这个 SQL 可以找到非空数组

SELECT * FROM rises WHERE array_length(ids, 1) > 0
--finds, e.g., 15 rows
Run Code Online (Sandbox Code Playgroud)

初始化:

CREATE TABLE rises(
    id bigserial, 
    d1 bigint DEFAULT 0, 
    ids bigint[] DEFAULT '{}', 
    PRIMARY KEY (id));
Run Code Online (Sandbox Code Playgroud)

为什么array_length可以找到非空数组,但对空数组不起作用?

postgresql array

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

日期范围中数组的元素?

我有一个日期数组,我想知道数组中的任何元素是否出现在给定的日期范围内。

例如(伪代码 - 不起作用,为了可读性而包装):

SELECT ARRAY['2017-01-01'::DATE, '2017-02-03'::DATE] && 
    daterange('2017-01-01', '2017-01-31', '[]');
Run Code Online (Sandbox Code Playgroud)

这个例子试图展示(虽然它不起作用)是我的日期数组和日期范围之间的值之间是否存在重叠。

理想情况下,我可以用集合来做,并确定两者之间是否存在联合,但似乎不可能将 daterange 对象转换为任何东西。

我确实设法让这个工作,但我不知道如何随后减少行:

SELECT daterange('2017-01-01', '2017-01-31', '[]') @> 
    unnest(ARRAY ['2017-01-01' :: DATE, '2016-07-30' :: DATE]);
Run Code Online (Sandbox Code Playgroud)

这将返回多行:

?column?
----------
 t
 f
(2 rows)
Run Code Online (Sandbox Code Playgroud)

有没有人对此有任何指示?任何帮助表示赞赏。

postgresql array range-types

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

如何选择不为空的数组?

为什么这如此棘手,令牌设置为什么,它不等于 null 也不等于空字符串?

SELECT lexemes
FROM ts_debug('This is a title')
WHERE alias = 'asciiword';

 lexemes 
---------
 {}
 {}
 {}
 {titl}
(4 rows)
Run Code Online (Sandbox Code Playgroud)

好吧..所以我想摆脱{}

SELECT lexemes
FROM ts_debug('This is a title')
WHERE alias = 'asciiword'
  AND lexemes <> '{}'
  AND lexemes <> ARRAY[]::text[]
  AND lexemes IS NOT NULL
  AND lexemes <> ARRAY[' ']
  AND lexemes <> ARRAY[null]::text[];
Run Code Online (Sandbox Code Playgroud)

我知道其中大多数都行不通。,但我完全困惑为什么<> '{}'不起作用<> ARRAY[]::text;。我该如何过滤掉这个?

postgresql null condition array postgresql-9.5

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

如何从任何数组中删除重复项并保留 PostgreSQL 中的顺序?

我正在寻找一种方法来消除 PostgreSQL 数组中的重复项,同时保留其元素的顺序。我目前拥有的是以下功能:

create function array_unique( anyarray ) 
  returns anyarray immutable strict language sql as $$
  select array( select distinct unnest( $1 ) ); $$;

create function array_unique_sorted( anyarray ) 
  returns anyarray immutable strict language sql as $$
  select array( select distinct unnest( $1 ) order by 1 ); $$;

/* ### TAINT there ought to be a simpler, declarative solution */
create function array_unique_stable( text[] )
  returns text[] immutable strict parallel safe language plpgsql as $$
  declare
    R         text[] …
Run Code Online (Sandbox Code Playgroud)

postgresql order-by duplication array

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

所有记录中数组列类型的唯一性

这里有张桌子

id serial primary key,
names varchar(20)[]
Run Code Online (Sandbox Code Playgroud)

它包含这样的记录

1, {"one", "two", "three"}
Run Code Online (Sandbox Code Playgroud)

然后,插入下一条记录(注意one数组元素已存在于现有记录中)

2, {"four", "one"}
Run Code Online (Sandbox Code Playgroud)

或者通过向数组添加一个元素来更新现有记录,但此类字符串元素已在其他记录中使用。

是否可以创建一个唯一的约束,不允许在所有行中全局重复数组内的元素,而不仅仅是在数组值本身内?

postgresql array

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

将数组值限制为允许的值集

我想设置一个 CHECK 约束来确保text[]列的元素仅包含某些值。

设置一个例子:

CREATE TABLE foo(
  countries text[]
);

INSERT INTO foo VALUES ('{"Morocco", "Mali", "Indonesia"}');
INSERT INTO foo VALUES ('{"Sokovia", "Mali"}');
Run Code Online (Sandbox Code Playgroud)

现在只允许“摩洛哥”、“马里”和“印度尼西亚”,因此第二行应该被约束拒绝。

我有一个“有效”的解决方案:

CHECK (array_length(
  array_remove(
    array_remove(
      array_remove(
        countries,
        'Indonesia'
      ), 'Mali'
    ), 'Morocco'
  ), 1) IS NULL)
Run Code Online (Sandbox Code Playgroud)

但这不太可读。

我也尝试过这个:

CHECK ((
  SELECT unnest(countries)
  EXCEPT
  SELECT unnest(array['Morocco', 'Mali', 'Indonesia'])
) IS NULL)
Run Code Online (Sandbox Code Playgroud)

但:

错误无法在检查约束中使用子查询

postgresql array check-constraints

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

优化匹配数组前 N 项的查询

我现在正在使用充满国际象棋游戏数据的 Postgres 数据库,其中每个游戏都是“记录”表中的一行。玩家的动作和这些动作的(可选)计算机评估都有自己的列并存储为数组。

我编写了一个查询来检索指定的开局动作序列的所有评估。(你可能认为计算机的评估会是一致的 - 但事实并非如此。)开局序列的长度是任意的 - 可以是一步,也可以是三十步。

下面是一个示例查询,它查找以相同的十步开局序列开始的所有游戏,然后对于每个带有评估的游戏,返回计算机对游戏中该点的评估 -

SELECT evaluation[10]
FROM records
WHERE moves[1:10]::text[] = ARRAY['b4', 'e5', 'Bb2', 'd6', 'Nf3', 'Nf6', 'g3', 'Bg4', 'Bg2', 'h5']::text[]
AND evaluation IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)

我不确定它是否相关,但移动数据始终是 2-6 个字符的字母数字字符串,并且计算机评估大部分是小数(正数和负数),但确实包括偶尔的特殊字符(强制将死者有一个 octothorpe前缀)。

这是表描述的相关片段 -

     Column      |              Type              | 
-----------------+--------------------------------+-
 id              | bigint                         | 
 moves           | character varying(255)[]       |  
 evaluation      | character varying(255)[]       | 
    "records_pkey" PRIMARY KEY, btree (id)
Access method: heap
Run Code Online (Sandbox Code Playgroud)

这是来自 EXPLAIN ANALYZE 的查询计划:

 Gather  (cost=1000.00..736354.70 rows=905 width=516) (actual time=28251.267..28253.139 rows=0 loops=1)
   Workers Planned: 2 …
Run Code Online (Sandbox Code Playgroud)

postgresql index optimization array postgresql-performance

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

数组字段上的 btree 索引实际上有什么作用吗?

在PG中你可以创建一个像这样的表

CREATE TABLE foo (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid (),
  name text NOT NULL,
  things text[] NOT NULL DEFAULT ARRAY[] ::text[]
)
Run Code Online (Sandbox Code Playgroud)

以及相关索引

CREATE INDEX foo_text ON foo USING btree (name, things);
Run Code Online (Sandbox Code Playgroud)

但很难找到有关其作用的信息。我继承了一个像这样的表(数亿行,尽管这个数组几乎总是有 0 或 1 个条目),并且索引确实在 pg_stat_all_indexes 中偶尔命中,所以至少在某些情况下可以发生了,但我也注意到,相对于其他索引,该索引占用了大量空间,并且清理速度要慢得多。 PG 中数组字段的索引有意义吗?btree

如果目标是能够找到things包含所提供的一个或多个值的行,是否有更好的方案?(假设我们此时无法将其正确规范化为它自己的表。)

我们期望查询会命中该索引,如下所示

SELECT id FROM foo
WHERE name = $1
AND $2::text = ANY(things)
Run Code Online (Sandbox Code Playgroud)
SELECT id FROM FOO
WHERE name = $1
AND things @> $2::text[]
Run Code Online (Sandbox Code Playgroud)

postgresql index array postgresql-performance

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