是否可以将枚举强制转换为整数?从1开始第一个元素

推荐答案

虽然不能像Catcall解释的那样将enum强制转换为整数,但可以使用特定于PostgreSQL且可能不兼容版本到版本的pg_enum系统目录表来获取序号表示.

regress=# CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');

regress=# select enumsortorder, enumlabel from pg_catalog.pg_enum 
regress-# WHERE enumtypid = 'happiness'::regtype ORDER BY enumsortorder;
 enumsortorder | enumlabel  
---------------+------------
             1 | happy
             2 | very happy
             3 | ecstatic
(3 rows)

这看起来很简单,但事实并非如此.注意:

regress=# ALTER TYPE happiness ADD VALUE 'sad' BEFORE 'happy';
regress=# ALTER TYPE happiness ADD VALUE 'miserable' BEFORE 'very happy';
regress=# SELECT * FROM pg_enum ;
 enumtypid | enumsortorder | enumlabel  
-----------+---------------+------------
    185300 |             1 | happy
    185300 |             2 | very happy
    185300 |             3 | ecstatic
    185300 |             0 | sad
    185300 |           1.5 | miserable
(5 rows)

由此可以看出,enumsortorder提供了订购,但没有固定的"距离".如果增加了对从枚举中删除值的支持,那么很可能也会在序列中创建"洞".

要获取枚举位置,需要使用row_number()窗口函数来获取排序,使用pg_typeof窗口函数来获取枚举类型的oid(regtype).当有多个具有相同标签的枚举时,需要使用此选项来确保返回正确的序号.

此功能完成以下任务:

CREATE OR REPLACE FUNCTION enum_to_position(anyenum) RETURNS integer AS $$
SELECT enumpos::integer FROM (
        SELECT row_number() OVER (order by enumsortorder) AS enumpos,
               enumsortorder,
               enumlabel
        FROM pg_catalog.pg_enum
        WHERE enumtypid = pg_typeof($1)
    ) enum_ordering
    WHERE enumlabel = ($1::text);
$$ LANGUAGE 'SQL' STABLE STRICT;

注:

  • 因为添加Pg值会改变顺序(如果在后面添加了STABLE个索引,则会改变顺序);所以
  • 不能在索引表达式中使用此选项;和
  • 它是STRICT,因为它应该为空输入返回空值

现在,您可以使用此函数将特定枚举的值设置为CREATE CASTinteger.不能为integer的所有枚举创建泛型转换,因为anyenum伪类型不能用于转换.例如,如果我想将demo happiness转换为整数,我会写:

CREATE CAST (happiness AS integer) WITH FUNCTION enum_to_position(anyenum);

之后我可以成功执行:

regress=# SELECT ('happy'::happiness)::integer;
 int4 
------
    2
(1 row)

请注意,这可能是一个insane件事要做,是不受支持的,很可能是一个可怕的 idea .当您从枚举中添加或(如果以后支持)删除值时,代码必须知道序号值为will change.

如果更改枚举的定义(除了在末尾添加新值),基于此强制转换创建的索引(只有在函数定义为不可变的情况下才可能)将开始产生疯狂和错误的结果,因为当您说函数是不可变的时,PostgreSQL会相信您.不要那样做.

Postgresql相关问答推荐

如何在Windows中安装sql for golang

Postgr不列出运算符和函数

使用PythonPolar在PostgreSQL中存储

Jsonb[]字段中的PostgreSQL否定&q;-0.0

在特定值的组聚合中添加标签列作为结果

如何获得一起满足数量要求的物品? (WHILE 循环还是 CTE?)postgresql

如何在 spring/JPA 中记录表和列名以防数据库错误

如何在不同的行中显示两列,避免重复并省略空条目

配置:错误:C 编译器无法在 Ubuntu 中创建可执行文件

Power BI + Postgres:只读用户

这个 Supbase 查询在 SQL ( Postgresql ) 中的类似功能是什么

将数组插入 Postgresql 数据库

如何引用使用 ON CONFLICT 中的函数的唯一索引?

IntegrityError:postgres 从转储恢复后,所有具有 ForeignKey 的模型/字段的id列中的空值

由于外键约束无法删除对象

向 Postgres 整数数组添加值

Python PostgreSQL 模块.哪个最好?

如何从 CSV 为 PostgreSQL 副本生成模式

Postgres 数据库文件保存在 ubuntu 中的什么位置?

postgresql 删除级联