我正在使用 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) 我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) 请向我解释这种行为。
此 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可以找到非空数组,但对空数组不起作用?
我有一个日期数组,我想知道数组中的任何元素是否出现在给定的日期范围内。
例如(伪代码 - 不起作用,为了可读性而包装):
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)
有没有人对此有任何指示?任何帮助表示赞赏。
为什么这如此棘手,令牌设置为什么,它不等于 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 数组中的重复项,同时保留其元素的顺序。我目前拥有的是以下功能:
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) 这里有张桌子
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)
或者通过向数组添加一个元素来更新现有记录,但此类字符串元素已在其他记录中使用。
是否可以创建一个唯一的约束,不允许在所有行中全局重复数组内的元素,而不仅仅是在数组值本身内?
我想设置一个 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)
但:
错误无法在检查约束中使用子查询
我现在正在使用充满国际象棋游戏数据的 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) 在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) array ×10
postgresql ×10
index ×2
condition ×1
duplication ×1
functions ×1
null ×1
optimization ×1
order-by ×1
plpgsql ×1
range-types ×1
string ×1