小编And*_*eKR的帖子

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

我想设置一个 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
查看次数

在连接上生成连续数字

对于 JOIN 中的每个右侧行,我想创建一个序列号,每个左侧行从 1(或 0)开始。

例子:

create table persons (person_id int, person_name text);
create table places (place_id int, person_id int, place_name text);
insert into persons values (10, 'Aulus Agerius'), (20, 'Numerius Negidius');
insert into places values (10, 10, 'Anytown'), (20, 10, 'Timbuktu'), (30, 20, 'Podunk');
Run Code Online (Sandbox Code Playgroud)
select person_name, place_name
from persons join places using (person_id)
order by person_id, place_id;
Run Code Online (Sandbox Code Playgroud)

小提琴

期望的结果:

人名 地名 地点顺序
奥鲁斯·阿杰里乌斯 任意镇 1
奥鲁斯·阿杰里乌斯 廷巴克图 2
内吉迪乌斯 波敦克 1

例如,2 inplace_seq表示“这是为该人找到的第二个地方”。

如何创建place_seq专栏?

postgresql

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

索引不用于日期范围条件

我是这样查询的:

SELECT count(*)
FROM orders
WHERE planned_shipping_date >= '2022-04-04'
AND planned_shipping_date < '2022-04-05'
Run Code Online (Sandbox Code Playgroud)

然后我遇到了这个答案,因为在更复杂的查询中它使查询更容易阅读,所以我重写了查询,如下所示:

SELECT count(*)
FROM orders
WHERE planned_shipping_date <@ daterange('2022-04-04', '2022-04-05')
Run Code Online (Sandbox Code Playgroud)

我相信它们在语义上是相同的,但看看计划:

Aggregate  (cost=76.91..76.92 rows=1 width=8) (actual time=1.066..1.068 rows=1 loops=1)
  ->  Index Only Scan using orders_planned_shipping_date_idx on orders  (cost=0.29..69.73 rows=2872 width=0) (actual time=0.067..0.646 rows=2813 loops=1)
        Index Cond: ((planned_shipping_date >= '2022-04-04'::date) AND (planned_shipping_date < '2022-04-05'::date))
        Heap Fetches: 0
Run Code Online (Sandbox Code Playgroud)
Aggregate  (cost=2753.57..2753.58 rows=1 width=8) (actual time=18.309..18.311 rows=1 loops=1)
  ->  Index Only Scan using orders_planned_shipping_date_idx on orders  (cost=0.29..2751.93 rows=655 width=0) …
Run Code Online (Sandbox Code Playgroud)

postgresql index range-types

4
推荐指数
1
解决办法
1532
查看次数

没有“有损”的“索引重新检查删除的行”是什么意思?

这是来自 Postgres 9.6 的 EXPLAIN ANALYZE 的一部分:

->  Bitmap Heap Scan on cities  (cost=90.05..806.49 rows=265 width=4) (actual time=4.733..45.772 rows=17 loops=1)
       Recheck Cond: (regexp_replace(regexp_replace(replace(replace(replace(replace(lower(name), 'ä'::text, 'ae'::text), 'ö'::text, 'oe'::text), 'ü'::text, 'ue'::text), 'ß'::text, 'ss'::text), 'strasse\M'::text, 'strasse'::text, 'g'::text), '\W'::text, ''::text, 'g'::text) % 'coerde'::text)
      Rows Removed by Index Recheck: 567
      Heap Blocks: exact=497
      ->  Bitmap Index Scan on city_lookup_index  (cost=0.00..89.98 rows=265 width=0) (actual time=4.229..4.229 rows=584 loops=1)
             Index Cond: (regexp_replace(regexp_replace(replace(replace(replace(replace(lower(name), 'ä'::text, 'ae'::text), 'ö'::text, 'oe'::text), 'ü'::text, 'ue'::text), 'ß'::text, 'ss'::text), 'strasse\M'::text, 'strasse'::text, 'g'::text), '\W'::text, ''::text, 'g'::text) % 'coerde'::text) …
Run Code Online (Sandbox Code Playgroud)

postgresql execution-plan explain postgresql-9.6

3
推荐指数
1
解决办法
654
查看次数

text_pattern_ops 和 COLLATE "C" 之间有区别吗?

name例如,如果我有一个带有排序规则的文本列tr-TR,并且我运行一个查询

SELECT * FROM t WHERE name LIKE 'a%'
Run Code Online (Sandbox Code Playgroud)

然后这将进行 seq 扫描。

如果我现在创建一个索引

CREATE INDEX ON t(name text_pattern_ops)
Run Code Online (Sandbox Code Playgroud)

上面的查询将变成位图扫描。但还有另一种技术可以达到相同的结果:

CREATE INDEX ON t(name COLLATE "C")
Run Code Online (Sandbox Code Playgroud)

这些方法完全等同还是存在差异?

postgresql index collation

3
推荐指数
1
解决办法
3527
查看次数

我可以编写不带 OR IS NULL 的 FULL OUTER JOIN 吗?

这里有一些可以使用的数据:

CREATE TABLE a (
    a_id   int  NOT NULL,
    a_prop text NOT NULL
);

CREATE TABLE b (
    b_id   int  NOT NULL,
    b_prop text NOT NULL
);

INSERT INTO a VALUES (1, 'blah'), (2, 'blah'), (4, 'not this one');
INSERT INTO b VALUES (1, 'blah'), (3, 'blah'), (5, 'not this one');
Run Code Online (Sandbox Code Playgroud)

现在我想编写一个返回的查询:

结果

一种可能性是:

SELECT *
FROM a
FULL OUTER JOIN b ON a_id = b_id
WHERE (a_prop = 'blah' OR a_prop IS NULL)
AND (b_prop = 'blah' OR b_prop IS …
Run Code Online (Sandbox Code Playgroud)

postgresql join syntax

3
推荐指数
1
解决办法
3927
查看次数