无法在Postgres中使用交叉表

时间:2014-04-15 01:16:44

标签: 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);

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

但如果我发表评论CREATE EXTENSION

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

我怎样摆脱这种恶性循环?这是一个众所周知的问题吗?

3 个答案:

答案 0 :(得分: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);

最近的相关答案更多信息:
How to use % operator from the extension pg_trgm?

可疑crosstab()

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

除此之外:不要使用value作为列名。即使Postgres容忍它。这是一个reserved word in standard SQL

答案 1 :(得分:3)

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

[编辑:如上所述,'所有架构都无法访问'应该读取'无法在所有架构上加载']

我了解到:

  1. 扩展程序只能加载到一个模式中 - 因此将其加载到“public”
  2. 您必须先从一个架构中手动删除扩展程序,然后才能将其加载到另一个架构中
  3. 您可以使用以下命令在pqsl中列出每个架构的已加载扩展名:\df *.crosstab
  4. [编辑:4。您可以通过search_path,通过在公共架构上加载或通过显式指定架构来访问扩展名)

答案 2 :(得分:3)

您可以将第一行更改为:

CREATE EXTENSION IF NOT EXISTS tablefunc;