[英]How to get a list column names and datatypes of a table in PostgreSQL?
[英]How to get the list of column names for all indexes on a table in PostgreSQL?
我有此查询以获取表上的索引列表:
SELECT
ns.nspname as schema_name,
tab.relname as table_name,
cls.relname as index_name,
am.amname as index_type,
idx.indisprimary as is_primary,
idx.indisunique as is_unique
FROM
pg_index idx
INNER JOIN pg_class cls ON cls.oid=idx.indexrelid
INNER JOIN pg_class tab ON tab.oid=idx.indrelid
INNER JOIN pg_am am ON am.oid=cls.relam
INNER JOIN pg_namespace ns on ns.oid=tab.relnamespace
WHERE ns.nspname = @Schema AND tab.relname = @Name
它似乎工作正常。 但是现在我需要查询列列表,并且在理解系统视图的工作方式时遇到了麻烦。
具体来说,我正在寻找的是:
理想情况下,我希望一次获得给定表的所有索引的上述项目。
请注意,我不仅在寻找列名。
使用系统目录信息功能pg_get_indexdef(index_oid)
获取完整的信息(包括索引表达式列表)-在针对pg_index
的查询中获取给定表的所有索引:
SELECT pg_get_indexdef(indexrelid) || ';' AS idx
FROM pg_index
WHERE indrelid = 'public.tbl'::regclass; -- optionally schema-qualified
有关:
如果您使用不合格的表名(无模式),则取决于当前的search_path
设置,并且可能会在其他模式中获得同名表的结果。
或者 ,您可以手动加入pg_attribute
以获得各个列,如以下相关答案所示:
关键要素是这样加入:
FROM pg_index idx
LEFT JOIN pg_attribute a ON a.attrelid = idx.indrelid
AND a.attnum = ANY(idx.indkey)
AND a.attnum > 0
关于pg_index.indkey
的手册:
这是
indnatts
值的数组,它们指示此索引索引的表列。 例如,值1 3
表示第一和第三表列构成索引条目。 关键列位于非关键(包含)列之前。 此数组中的零表示相应的索引属性是表列上的表达式,而不是简单的列引用。
从技术上讲,不需要AND a.attnum > 0
因为没有a.attnum = 0
。 但这使查询更清晰,不会受到伤害。 手册:
普通列从1开始编号。 系统列(例如oid)具有(任意)负数。
请注意, “列名列表”实际上也可以包含表达式。 而且自Postgres 11起,也有“ included”列(那里没有表达式)。 pg_get_indexdef()
处理所有可能的复杂情况。
您可以从系统目录中一起困惑它,如Erwin Brandstetter所详述。
这是一个查询,它将返回您想要的信息:
SELECT i.indexrelid::regclass AS indexname,
k.i AS index_order,
i.indnkeyatts,
coalesce(a.attname,
(('{' || pg_get_expr(
i.indexprs,
i.indrelid
)
|| '}')::text[]
)[k.i]
) AS index_column,
i.indoption[k.i - 1] = 0 AS ascending,
k.i <= i.indnkeyatts AS is_key
FROM pg_index i
CROSS JOIN LATERAL unnest(i.indkey) WITH ORDINALITY AS k(attnum, i)
LEFT JOIN pg_attribute AS a
ON i.indrelid = a.attrelid AND k.attnum = a.attnum
WHERE i.indrelid = 'schemaname.tablename'::regclass;
该查询仅适用于PostgreSQL v11及更高版本(但v11之前没有涵盖的索引)。
另外,如果索引表达式包含逗号,查询将失败;否则,查询将失败。 我不知道该如何解决。
版本10.4
SELECT idx.indexrelid::regclass AS indexname,
k.i AS index_order,
--i.indnkeyatts,
coalesce(att.attname,
(('{' || pg_get_expr(
idx.indexprs,
idx.indrelid
)
|| '}')::text[]
)[k.i]
) AS index_column,
pg_index_column_has_property(idx.indexrelid,k.i::int,'asc') AS ascending,
k.i != -1 AS is_key
FROM pg_index idx
CROSS JOIN LATERAL unnest(idx.indkey) WITH ORDINALITY AS k(attnum, i)
LEFT JOIN pg_attribute AS att
ON idx.indrelid = att.attrelid AND k.attnum = att.attnum
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.