我希望从PostgreSQL的一列不同值中创建一个枚举。我想要使用查询来获取该类型的所有可能值,而不是从所有标签中创建枚举。我期望的代码如下:
CREATE TYPE genre_type AS ENUM
(select distinct genre from movies);
但我没有被允许这样做。有没有任何方法可以实现这个目标?
我希望从PostgreSQL的一列不同值中创建一个枚举。我想要使用查询来获取该类型的所有可能值,而不是从所有标签中创建枚举。我期望的代码如下:
CREATE TYPE genre_type AS ENUM
(select distinct genre from movies);
如果类型种类是动态的,即您会不时地创建新类型并重命名旧类型,或者如果您希望将附加信息保存在每个类型中,则值得考虑 @mu的建议 和@Marcello的实现 - 除此之外,您应该只使用类型text
而不是varchar(20)
,并考虑使用ON UPDATE CASCADE
来进行fk约束。
除此之外,这是您要求的步骤:
DO
$$
BEGIN
EXECUTE (
SELECT format('CREATE TYPE genre_type AS ENUM (%s)'
,string_agg(DISTINCT quote_literal(genre), ', '))
FROM movies);
END
$$
DO
命令(适用于PostgreSQL 9.0+版本)。quote_literal()
进行了正确转义。string_agg()
函数(适用于PostgreSQL 9.0+版本)来聚合字符串。http://www.postgresql.org/docs/9.1/static/datatype-enum.html
枚举类型是由一组静态有序的值组成的数据类型。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;
DO $$
DECLARE temp text;
BEGIN
SELECT INTO temp string_agg(DISTINCT quote_literal(genre),',') FROM movies;
EXECUTE 'CREATE TYPE foo AS ENUM ('||temp||')';
END$$;
{{链接1:fiddle}}
string_agg()
之外使用 DISTINCT
可能是一个打字错误? - Erwin BrandstetterSELECT
,然后从中复制名称。CREATE TYPE name AS ENUM ( [ 'label' [, ... ] ] )
,所以不在那里的关键字是expression
。这意味着在ENUM
之后可能没有表达式,而只有标签列表。INSERT ... SELECT ...
填充),然后创建一个指向该表的外键
。