标签: postgresql

显示当前行“连胜”

我需要在查询中显示每行的连续赢/输,因此根据下表,查询应返回“预期”列。我尝试了一些窗口函数的方法,但没有成功。

create table matches (player text, dt date,  is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
Run Code Online (Sandbox Code Playgroud)
create table matches (player text, dt date,  is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, …
Run Code Online (Sandbox Code Playgroud)

postgresql gaps-and-islands

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

按数组重叠分组

我有一个带有 id 和集群的 PostgreSQL 表,如下所示:

CREATE TABLE w (id bigint, clst int);
INSERT INTO w (id,clst)
VALUES 
  (1,0),
  (1,4),
  (2,1),
  (2,2),
  (2,3),
  (3,2),
  (4,2),
  (5,4),
  (6,5);
Run Code Online (Sandbox Code Playgroud)

如果聚合按 id 分组的集群,您可以看到集群数组中存在重叠值:

select id, array_agg(clst) clst from w group by id order by id;
 id |  clst
----+---------
  1 | {0,4}
  2 | {1,2,3}
  3 | {2}
  4 | {2}
  5 | {4}
  6 | {5}
Run Code Online (Sandbox Code Playgroud)

即集群4覆盖id 1和5,集群2覆盖id 2、3和4,而集群5只对应一个id。

我现在如何聚合按集群数组重叠分组的 id?即预期的结果是:

 id      | clst
---------+-------
 {1,5}   | {0,4,4}
 {2,3,4} | {1,2,3,2,2}
 {6}     | …
Run Code Online (Sandbox Code Playgroud)

postgresql

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

跨多对多关系查询“全部”

想象一下三个表的设置,User、Group 和 UserGroup,其中 UserGroup 由指向每个 User 和 Group 表的简单外键组成。

User
----
id
name

Group
-----
id
name

UserGroup
---------
user_id
group_id
Run Code Online (Sandbox Code Playgroud)

现在,我想编写一个查询,选择所有指定组中的所有用户。例如,从用户是“group1”、“group2”和“group3”中的每一个的一部分的用户中选择*。

使用 Django ORM 查询,我会做类似的事情

users = (
    User.objects
    .filter(user_group__group_id=group1.id)
    .filter(user_group__group_id=group2.id)
    .filter(user_group__group_id=group2.id)
)
Run Code Online (Sandbox Code Playgroud)

这将为每次调用产生一个连接.filter,例如

SELECT * FROM users
INNER JOIN user_group g1 ON g1.user_id = id
INNER JOIN user_group g2 ON g2.user_id = id
INNER JOIN user_group g3 ON g3.user_id = id
WHERE g1.group_id = %s
  AND g2.group_id = %s
  AND g3.group_id = %s
Run Code Online (Sandbox Code Playgroud)

如果我要查询一个更大的集合来匹配,这会变得有点麻烦。

那么有什么更好的方法来做到这一点呢?如果我要问“任何”而不是“所有”,如果是一个简单的问题

SELECT …
Run Code Online (Sandbox Code Playgroud)

postgresql relational-division many-to-many

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

从 Postgres 11 中的服务器端过程返回多个结果集

Postgres 咨询公司的这篇博文提到 Postgres 11 中新的服务器端过程支持将能够返回多个结果集。

? 这个特性确实出现在 Postgres 11 版本中吗?

如果是这样,你能简单解释一下它是如何工作的吗?显示一些代码示例?

postgresql stored-procedures postgresql-11

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

字段中的字数统计(所有且唯一) - 有没有更优雅/最佳的方式?

回答这个问题

鉴于此表(根据问题构建):

CREATE TABLE wordcount (id SERIAL NOT NULL PRIMARY KEY, description TEXT NOT NULL);

INSERT INTO wordcount (description) VALUES ('What a great day');
INSERT INTO wordcount (description) VALUES ('This is a product. It is useful');
Run Code Online (Sandbox Code Playgroud)

产生这个结果:

     id  | word_count | unique_word_count |  Description                        
---------+------------+-------------------+---------------
     1   |  4         | 4                 | What a great day
     2   |  7         | 6                 | This is a product. It is useful
Run Code Online (Sandbox Code Playgroud)

我给出了(正确的)答案,你可以在这里找到。

然而,在评论中,OP 然后又问了一个问题——如果有问题的字符串是['a', ' ', ' ', …

postgresql optimization string-manipulation query-performance

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

如何从命令行将变量传递给 PL/pgSQL 代码?

我正在从命令行运行 psql 脚本,其中的变量类似于:

psql ...... -v now_utc=$NOW_UTC 
Run Code Online (Sandbox Code Playgroud)

然后我想在我的脚本中使用它,例如:

$$
DECLARE
   _now_date timestamp := :now_utc;
BEGIN
  -- do something
END
$$
Run Code Online (Sandbox Code Playgroud)

但我得到了一个错误,如:

syntax error at or near ':'
Run Code Online (Sandbox Code Playgroud)

一旦我从:now_utc变为now(),脚本就很好,它就像一个魅力。

问题是如何将变量从命令行传递给 PL/pgSQL 代码?

postgresql psql plpgsql string-manipulation

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

为什么要在我的关系数据库中实现外键?

今天早些时候,我与我的专业同行就我们公司数据库中的外键话题引发了一场相当意外的辩论。简而言之,一位比我年长的软件工程师说他不喜欢我对我们的一个存储库所做的提交,因为我在两个表之间实现了外键关系。他的论点是他不喜欢外键,因为它们限制了可以插入数据库的数据,他认为这会使数据库更难使用。(注意:他的论点一般反对外键,而不仅仅是我在我们的应用程序中提出的轶事外键约束。他认为外键约束是现代关系数据库系统中的一个设计缺陷。)

此时,我完全措手不及,我们的老板暂时选择站在高级开发人员一边,要求我从我正在处理的错误修复的实现中删除外键。我正在修复的错误实际上源于使我们的 ORM 感到困惑的关系不一致(这本身还有一些不足之处,但这是一个不同的故事),虽然我试图向我的团队解释这一点,但每个人都站在高级dev & 我被告知要回到绘图板并重新实现我的数据库修复,而不依赖于外键约束。换句话说,我被要求在没有 RDBMS(posgres,如果重要的话)的内置关系管理工具的情况下进行关系管理。

我重申这不是修复错误的正确方法,此时我的老板告诉我讨论占用了太多时间,如果我想辩论正式 FK 约束的优点,我需要以后再做……我打算这样做,但我也觉得我的任务是争论为什么水是湿的。

当我进入这场辩论时,我想用尽可能多的事实来支持外键的使用。我知道实施合理的 FK 约束:

  1. 作为防止关系不一致的自动护栏(即,防止“垃圾数据”(这是我目前正在使用的系统的一个明显问题)),
  2. 向正在检查数据库模式的人阐明两个相关表之间的高级关系上下文,以及
  3. 可以提高数据库查询操作的性能

......但我想知道在这个主题上是否还有其他我可能遗漏的要点,我应该用这些要点来应对这场辩论。我应该确保向我的老板和同事提出哪些其他好处?(或者真的有范式转变远离 FK 约束,当它发生时我一直把头埋在石头下?)

postgresql foreign-key relational-theory

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

Postgres 中具有部分索引和大 In-clause 时的错误执行计划

Postgres 似乎总是使用顺序扫描,它可以使用部分索引来仅获取索引扫描。它仅在一个从句超过 100 个元素时发生。

鉴于下表:

create table foo(id bigint primary key, bar bigint); 

insert into foo (id, bar) 
select g.id, case when id % 1000 = 0 then id else null end
from generate_series(1, 10000000) AS g (id) ;

--Create partial index
create unique index ix_foo_bar on foo(bar) where bar is not null;

analyze foo;
Run Code Online (Sandbox Code Playgroud)

并给出以下带有大语句的查询:

explain analyze select count(*) from foo where bar in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101);
Run Code Online (Sandbox Code Playgroud)

查询计划显示顺序扫描。它很慢,而且成本很高:

QUERY PLAN                                                                             
------------------------------------
 Finalize Aggregate  (cost=612955.35..612955.36 rows=1 width=8) (actual time=254.605..254.605 rows=1 loops=1)
   -> …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan postgresql-11

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

是否可以在 PostgreSQL 中使用单个语句更新插入到自引用表中?

如果我有一张桌子A,就像这样:

A {
 id SERIAL
 title TEXT
 ...
 parentId INT references A.id via a foreign key constraint
}
Run Code Online (Sandbox Code Playgroud)

我正在从源表中提取数据 - A_SOURCE- 没有parentId列的地方。取而代之的是一parentTitle列。所以源表看起来像这样:

A_SOURCE {
  title TEXT
  parentTitle TEXT
}
Run Code Online (Sandbox Code Playgroud)

我开始编写一个 upsert 语句以A通过从表中选择插入到表中,A_SOURCE然后才意识到我无法轻松地parentTitle将源中的列解析parentId为目标中的 a。

由于我无法确定在处理子项时是否已插入父项,因此连接或子查询可能不会返回任何结果。

我的 upsert 语句看起来像这样:

with source as (
  select
   title
   parentTitle
  from A_SOURCE 
)

insert into A
select
title
... I don't think I can resolve to parentId here?
from source
on …
Run Code Online (Sandbox Code Playgroud)

postgresql upsert self-join

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

由于缺少 oid 运算符,无法从 pgAdmin4 中的表中输出数据

我目前在本地运行 Postgresql 10.6,我使用 PgAdmin 4.12 与之交互,直到今天一切都运行良好。但是今天我在 pgAdmin 查询编辑器中运行了以下查询:

SELECT * FROM test_table LIMIT 100
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

ERROR:  operator does not exist: - oid at character 125
HINT:  No operator matches the given name and argument type. You might need to add an explicit type cast.
STATEMENT:  SELECT at.attname, at.attnum, ty.typname
        FROM pg_attribute at LEFT JOIN pg_type ty ON (ty.oid = at.atttypid)
        WHERE attrelid=-1519044407::oid AND attnum = ANY (
            (SELECT con.conkey FROM pg_class rel LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid
            AND …
Run Code Online (Sandbox Code Playgroud)

postgresql select table pgadmin-4 objectid

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