小编Erw*_*ter的帖子

查询父表并获取子表列

我有两张表,一张继承了另一张:

CREATE TABLE parent (
    col1 INTEGER
);

CREATE TABLE child (
    col2 INTEGER
) INHERITS( parent );

// Insert some data
INSERT INTO parent( col1 ) VALUES( 1 );
INSERT INTO child( col1, col2 ) VALUES( 2, 2 );
Run Code Online (Sandbox Code Playgroud)

有什么方法可以查询父表,使其获取子表的所有列?

此查询仅返回父列:

SELECT * FROM parent;

| col1 |
| ---- |
| 1    |
| 2    |
Run Code Online (Sandbox Code Playgroud)

我想要的查询将返回父和子中的所有列:

SELECT ...  -- some query, with desired result:

| col1 | col2 |
| ---- | ---- |
| 1    | …
Run Code Online (Sandbox Code Playgroud)

postgresql database-design select inheritance

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

跨表唯一

我有一个包含用户的表。每个用户都有一个主电子邮件和一个指示该用户是否被删除的标志(我们从不硬删除用户)。

但是,每个用户还可以拥有额外的电子邮件。

无论如何,电子邮件地址必须是唯一的,我想在数据库级别强制执行这一点。对于主要电子邮件地址来说这很简单。我可以简单地添加一个带有WHERE not is_deleted限制的 UNIQUE 索引,以便可以重新使用已删除的用户的电子邮件。

然而,对于辅助电子邮件来说,这就更加棘手。

  • 如果我将它们存储在数组字段中的同一个表中,我可能不仅会失去对它们进行索引的能力(我们有超过 5 万的用户,并且需要能够通过电子邮件进行搜索,所以这是不行的),而且到目前为止据我所知,我也不能将唯一的索引/约束放入数组中。
  • 如果我使用一个单独的表(这显然更干净),我必须将is_deleted用户的标志复制到该表,这也很丑陋,但允许我简单地使用 UNIQUE 索引与WHERE not is_deleted.

有没有更好的解决方案来实现我想要做的事情?

postgresql foreign-key database-design constraint unique-constraint

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

删除主键而不删除索引

是否可以在不删除索引的情况下删除表上的主键约束?我有一种情况,我想删除PRIMARY KEY以摆脱NOT NULL约束并将其设置为另一个列对。我想避免删除和重新创建索引。可以只PRIMARY KEY删除索引上的“属性”吗?删除约束会删除索引。

我使用的是 PostgreSQL 9.1 版。

postgresql index primary-key ddl

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

即使函数中止,也会在 UDF 中持久插入

我有一个相当复杂的 UDF(在一堆表中移动并创建一堆新表),其中可能会发生多次中止。在每次操作之前,我想记录操作发生的时间和查询本身。UDF 如下所示:

log function_start

log sql1
execute sql1

log sql2
execute sql2

...

log sqlN
execute sqlN

log function_end
Run Code Online (Sandbox Code Playgroud)

每条日志语句都意味着向下表中插入一条新记录:

CREATE TABLE backup_logs
(
  id serial NOT NULL,
  t timestamp with time zone default now(),
  sql text,
  CONSTRAINT backup_logs_pkey PRIMARY KEY (id)
)
Run Code Online (Sandbox Code Playgroud)

如果发生中止,我希望sql1, sql2, ... sqlN回滚,但inserto into backup_logs会继续存在。问题:我怎样才能实现这一目标?

postgresql insert transaction plpgsql postgresql-9.4

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

选择具有某些条件的计数

使用 Postgres 9.4,我有一个page_views包含一page列的表。我想选择所有不同的页面并在它们之前进行计数并按降序对它们进行排序。我还希望在过去 24 小时内最少计数 20。所以它看起来像这样:

120 / home
 56 / about
 24 / locations
Run Code Online (Sandbox Code Playgroud)

我刚在想:

select count(*),page from page_views group by page where count(*) > 20;
Run Code Online (Sandbox Code Playgroud)

但这不起作用。这该怎么做?

postgresql aggregate postgresql-9.4

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

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

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万
查看次数

如何在 PostgreSQL 中旋转

表中有以下数据:

ID     Category   Value
1234   Cat01      V001
1234   Cat02      V002
1234   Cat03      V003
1234   Cat03      V004
1234   Cat03      V005
Run Code Online (Sandbox Code Playgroud)

我想要以下输出:

ID     Cat01  Cat02   Cat03
1234   V001   V002    V003
1234   V001   V002    V004
1234   V001   V002    V005
Run Code Online (Sandbox Code Playgroud)

我想要实现的输出是一种数据透视表,其中我将所有值垂直放置在一个表中,并且我希望将这些值水平放置,并将类别作为列。但是有些类别具有多个值,在这种情况下,我需要重复所有其他类别的值并为每个重复值创建一行

如何在 PostgreSQL 中完成?

postgresql pivot

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

如何使用变量的值设置列 DEFAULT

在设置使用随机 UUID 作为主键的数据库的脚本中,我有:

CREATE TABLE alpha (id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), value INT);
CREATE TABLE beta (aref UUID REFERENCES alpha (id));

INSERT INTO alpha (value) VALUES (42);
Run Code Online (Sandbox Code Playgroud)

然后通过外键,让“alpha”中的记录成为插入“beta”表的默认目标:

DO $$
    DECLARE l_id UUID;
    BEGIN
        SELECT alpha.id FROM alpha INTO l_id;
        ALTER TABLE beta ALTER COLUMN aref SET DEFAULT l_id;
    END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
ERROR:  column "l_id" does not exist
CONTEXT:  SQL statement "ALTER TABLE beta ALTER COLUMN aref SET DEFAULT l_id"
PL/pgSQL function inline_code_block line 1 at SQL statement …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql default-value alter-table plpgsql

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

如何在 Postgres 中一次更新多个表?

我有几个结构完全相同的表,我需要更新所有表中的值。

为此,我尝试构建以下脚本:

DO
$do$
DECLARE
  i pg_tables%rowtype;
BEGIN
FOR i IN SELECT * FROM pg_catalog.pg_tables where schemaname like 'public' and tablename like '%_knex_migrations'
LOOP
    UPDATE i.tablename SET name = replace(name, '.js', '.ts');
END LOOP;
END
$do$;
Run Code Online (Sandbox Code Playgroud)

我可以看到它i.tablename具有正确的值(我插入到 tmp 表中进行检查),但更新失败。

name: error
length: 223
severity: ERROR
code: 42P01
internalPosition: 8
internalQuery: UPDATE i."tablename" SET name = replace(name, '.js', '.ts')
where: PL/pgSQL function inline_code_block line 7 at SQL statement
file: parse_relation.c
line: 965
routine: parserOpenTable
Run Code Online (Sandbox Code Playgroud)

只是声明i.tablename上的插件UPDATE不起作用。 …

postgresql dynamic-sql plpgsql update

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

选择中的 jsonb_array_elements() 似乎将左连接变成了内连接

PostgreSQL 9.6。

create table jon.vins (vin citext primary key);
insert into jon.vins values
('3GNAXUEV1KL221776'),
('3GNAXHEV2KS548975');

CREATE TABLE jon.describe_vehicle (
  vin citext primary key,
  response jsonb);
Run Code Online (Sandbox Code Playgroud)

jon.describe_vehicle 仅包含 1 vin,3GNAXHEV2KS548975 的数据;

这个查询:

    select a.vin,
      b.response->'attributes'->>'bestMakeName' as make
    from jon.vins a
    left join jon.describe_vehicle b on a.vin = b.vin;
Run Code Online (Sandbox Code Playgroud)

返回我所期望的,每个 vin in 一行jon.vins

        vin        |   make    
-------------------+-----------
 3GNAXUEV1KL221776 | 
 3GNAXHEV2KS548975 | Chevrolet
(2 rows)
Run Code Online (Sandbox Code Playgroud)

但是这个查询:

    select a.vin,
      jsonb_array_elements(b.response->'style')->'attributes'->>'name' as style
    from jon.vins a
    left join jon.describe_vehicle b on a.vin = …
Run Code Online (Sandbox Code Playgroud)

postgresql set-returning-functions

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