11

OSX 10.9.2 上的 Postgres 9.2.1。

如果我运行以下交叉表示例查询:

CREATE EXTENSION tablefunc; 

CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');

SELECT *
FROM crosstab(
  'select rowid, attribute, value
   from ct
   where attribute = ''att2'' or attribute = ''att3''
   order by 1,2')
AS ct(row_name text, category_1 text, category_2 text, category_3 text);

我得到:ERROR: extension "tablefunc" already exists

但是如果我注释掉CREATE EXTENSION

我得到:ERROR: function crosstab(unknown) does not exist

我怎样才能摆脱这个恶性循环?这是一个已知问题吗?

4

3 回答 3

13

您可以将第一行更改为:

CREATE EXTENSION IF NOT EXISTS tablefunc;
于 2017-12-05T07:24:36.133 回答
7

我的问题是'tablefunc'扩展是在我的数据库中的一个特定模式上定义的,并且不能被其中的所有模式访问。

[编辑:如上所述,“所有模式都无法访问”应为“无法在所有模式上加载”]

我了解到:

  1. 扩展只能加载到一个模式中 - 所以将其加载到“公共”中
  2. 您必须先从一个架构中手动删除扩展,然后才能将其加载到另一个架构中
  3. 您可以使用以下命令在 pqsl 中列出每个模式已加载的扩展:\df *.crosstab

[编辑:4. 您可以通过 search_path、将其加载到公共架构或显式指定架构来访问扩展]

于 2014-04-15T01:39:46.763 回答
4

你的回答有误会:

并且其中的所有模式都无法访问。

同一数据库中的所有会话都可以访问同一数据库中的所有模式(只要授予权限)。这是设置的问题search_path。模式的工作方式很像文件系统中的目录/文件夹。

或者,您可以对函数(甚至运算符)进行模式限定,以独立于search_path

SELECT *
FROM my_extension_schema.crosstab(
    $$select rowid, attribute, "value"
      from   ct
      where  attribute IN ('att2', 'att3')
      order  by 1,2$$
   ,$$VALUES ('att2'), ('att3')$$
   ) AS ct(row_name text, category_2 text, category_3 text);

最近与更多信息相关的答案:
如何使用扩展 pg_trgm 中的 % 运算符?

可疑crosstab()

您的查询返回了属性'att2''att3',但列定义列表具有category_1, category_2, category_3与查询不匹配的三个类别 ( )。
我删除category_1并添加了第二个参数 crosstab() - “安全”版本。更多详细信息:
PostgreSQL 交叉表查询

旁白:不要value用作列名。即使 Postgres 容忍它。它是标准 SQL 中的保留字

于 2014-04-15T02:15:57.647 回答