如何像在 MySQL 中一样查询 PostgreSQL 枚举?

use*_*092 5 postgresql enum where

在 MySQL 中使用下表:

CREATE TABLE bob(foo ENUM('a','b','c'));

INSERT INTO bob (foo) VALUES ('a'),('b'),('c'),('a'),('a');

SELECT * FROM bob WHERE foo >= 2;
+------+
| foo  |
+------+
| b    |
| c    |
+------+
Run Code Online (Sandbox Code Playgroud)

使用 PostGres 中的下表:

CREATE TYPE stuff AS ENUM ('a', 'b', 'c');
INSERT INTO bob (foo) VALUES ('a'), ('b'), ('b'), ('c'), ('c');
SELECT * FROM bob WHERE foo > 2;
(HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.)
Run Code Online (Sandbox Code Playgroud)

我已经读到有一些奇特的方法可以解决这个问题,但是有没有办法创建一个模仿 MySQL 功能的类型?或者是否有具有我想要的功能的数据类型?(能够在插入时检查字符串,还可以针对聚合生成 where 案例)。

Eva*_*oll 6

我认为您ENUM对 MySQL 违反规范和愚蠢有误解。它们在 MySQL 和 PostgreSQL 中都不同,但它们在 PostgreSQL 中更明显不同。您正在尝试无缝查询内部表示细节。我真的很高兴 PostgreSQL 阻止了它。

而是使用ENUM 支持功能

CREATE TYPE stuff AS ENUM ('a', 'b', 'c');
SELECT * FROM enum_range('b'::stuff, NULL);
Run Code Online (Sandbox Code Playgroud)

这将返回从“b”到枚举的无界顶部的所有内容(在本例中为“c”)

现在创建一个表并插入一些值,

CREATE TABLE bob ( foo stuff );
INSERT INTO bob (foo) VALUES ('a'),('b'),('c'),('a'),('a');
Run Code Online (Sandbox Code Playgroud)

现在要查询它,请执行以下操作

SELECT *
FROM bob
WHERE foo = ANY(enum_range('b'::stuff, NULL));
Run Code Online (Sandbox Code Playgroud)

或者更简单地说,正如 Abelisto 在评论中所建议的那样。请注意,细节仍然是抽象的。你不知道排序的顺序b是什么,

WHERE foo >= 'b'::stuff;
WHERE foo >= 'b';
Run Code Online (Sandbox Code Playgroud)

默认情况下,枚举是有序的。在 PostgreSQL 中,它们存储为 int4。在 MySQL 中,它们存储为 int2 或 int1。但是,它们的实现不应向用户透露。

试想一下,在上面的查询中,添加值后从数据库重新加载可能会重新排序枚举。然后您的查询中断,因为您已假定2.

也可以看看,