无法在Postgres中使用交叉表

Bla*_*ack 7 postgresql crosstab search-path

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);
Run Code Online (Sandbox Code Playgroud)

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

但是如果我注释掉 CREATE EXTENSION

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

我如何摆脱这个恶性循环?这是一个已知问题吗?

Bla*_*ack 7

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

[编辑:如上所述,“不能被所有模式访问”应该读作“不能在所有模式上加载”]

我了解到:

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

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


akb*_*bin 7

您可以将第一行更改为:

CREATE EXTENSION IF NOT EXISTS tablefunc;
Run Code Online (Sandbox Code Playgroud)


Erw*_*ter 5

你的回答有一个误解:

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

同一数据库中的所有模式都可以被同一数据库中的所有会话访问(只要授予权限)。这是设置的问题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);
Run Code Online (Sandbox Code Playgroud)

更多的:

可疑crosstab()

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

旁白:即使 Postgres 允许,也
不要用作列名称。value它是标准 SQL 中的保留字