Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PostgreSQL中从SQL查询创建枚举?_Postgresql - Fatal编程技术网

如何在PostgreSQL中从SQL查询创建枚举?

如何在PostgreSQL中从SQL查询创建枚举?,postgresql,Postgresql,我想从PostgreSQL中列的不同值创建一个枚举。我不想从所有标签创建枚举,而是希望使用查询来创建它,以获取该类型的所有可能值。我期待着这样的事情: CREATE TYPE genre_type AS ENUM (select distinct genre from movies); 但我不被允许这样做。有没有办法做到这一点 一个简单的方法是在客户机中执行SELECT,然后从中复制名称 我想这就是你能做的一切。如果查看文档,您会注意到有编写的CREATE TYPE name AS EN

我想从PostgreSQL中列的不同值创建一个枚举。我不想从所有标签创建枚举,而是希望使用查询来创建它,以获取该类型的所有可能值。我期待着这样的事情:

CREATE TYPE genre_type AS ENUM
   (select distinct genre from movies);

但我不被允许这样做。有没有办法做到这一点

一个简单的方法是在客户机中执行
SELECT
,然后从中复制名称

我想这就是你能做的一切。如果查看文档,您会注意到有编写的
CREATE TYPE name AS ENUM(['label'[,…])
,因此没有的是关键字
expression
。这意味着在
ENUM
之后可能没有表达式,只有标签列表

你可能想按照@muistooshort的建议创建一个类型表(你可以用
插入…选择…
)然后为该表创建一个
外键。

我认为你不能通过设计来做到这一点

枚举(enum)类型是包含静态、有序 一组值

SELECT子句中的“DISTINCT”关键字使我认为您的模式没有完全规范化

例如:

CREATE TABLE movies(
    ...
    genre VARCHAR(20)
    ...
);

SELECT DISTINCT genre FROM movies;
应成为:

CREATE TABLE genres(
    id SERIAL PRIMARY KEY,
    name VARCHAR(20)
);

CREATE TABLE movies (
    id SERIAL PRIMARY KEY,
    title VARCHAR(200),
    genre INTEGER REFERENCES genres(id)
);

SELECT name FROM genres;

这可以在pgsql中完成。下面是执行此操作的内联代码:

DO $$
  DECLARE temp text;
BEGIN
    SELECT INTO temp string_agg(DISTINCT quote_literal(genre),',') FROM movies;
    EXECUTE 'CREATE TYPE foo AS ENUM ('||temp||')';
END$$;

如果流派类型在任何方面都是动态的,即您创建新的流派类型并不时重命名旧的流派类型,或者如果您希望保存每个流派类型的附加信息,则值得考虑-除非您只使用type
text
而不是
varchar(20)< />代码>并考虑“更新级联”<代码> > FK约束> 

除此之外,以下是您要求的配方:

DO
$$
BEGIN
EXECUTE (
    SELECT format('CREATE TYPE genre_type AS ENUM (%s)'
                  ,string_agg(DISTINCT quote_literal(genre), ', '))
    FROM  movies);
END 
$$
为此,您需要动态SQL。简单的方法是使用命令(PostgreSQL 9.0+)。
确保使用
quote\u literal()
正确转义字符串

我使用(PostgreSQL 9.0+)聚合字符串。

为此,您真的需要
枚举吗?对于
genres
表来说,一个简单的FK不是也可以吗?@muistoshort可能是OP想要一个常量枚举,与对表所做的更改无关。FK在大多数情况下都是一个很好的解决方案,但并非总是如此。
DISTINCT
string\u agg()
之外可能是一个拼写错误?@ErwinBrandstetter不仅仅是一个拼写错误,当我看到op使用它时,我忘记了它,然后把它放在了某个地方。谢谢