Ama*_*nda 7 postgresql order-by array enum
我在当前存储为 VARCHAR 的 Postgres 数据库中有一个非常基本的分类列。我可以选择每个计数:
我虽然添加一个ORDER BY array_position()会做到这一点:
SELECT color, count(*)
FROM research
GROUP BY color
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);
Run Code Online (Sandbox Code Playgroud)
但我看到一个类型错误:
ERROR: function array_position(text[], character varying) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 98
Run Code Online (Sandbox Code Playgroud)
我需要投射什么color才能使用该array_position功能对其进行排序?
Eva*_*oll 10
你有一张像,
CREATE TABLE research(colors)
AS VALUES ('Blue'), ('Orange'), ('Yellow');
Run Code Online (Sandbox Code Playgroud)
ENUM 类型您有一个枚举的颜色列表。所以这里最简单的事情是使用ENUM 类型
CREATE TYPE colors AS ENUM ('Red','Orange','Yellow','Green','Blue');
Run Code Online (Sandbox Code Playgroud)
然后
ALTER TABLE research
ALTER COLUMN colors -- myColorsColumn
SET DATA TYPE colors
USING (colors::colors); -- myColorsColumn::NewType
Run Code Online (Sandbox Code Playgroud)
现在它更快、更高效、更清洁。更多的胜利。更多欢乐。等ENUM在内部存储为 4 字节。
ORDER BY colors
Run Code Online (Sandbox Code Playgroud)
这就是你所需要的。
但是,您拥有上帝赐予的权利,可以像对待任何其他不支持 ENUM 类型的数据库一样对待它,
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);
Run Code Online (Sandbox Code Playgroud)
我认为这很好,但我相信在实现中存在限制,
ARRAY['foo', 'bar', 'baz']
Run Code Online (Sandbox Code Playgroud)
本质上是
ARRAY['foo', 'bar', 'baz']::text
Run Code Online (Sandbox Code Playgroud)
这意味着您需要(速度无关紧要,因为两个选项执行相同)
使color本机的列text。这可以在调用中完成,或者您可以实际修改表和应该。在 PostgreSQL 中,没有什么应该是varchar没有限制的(因为这只是文本的并行类型),并且很少有事情应该varchar有限制(因为没有优势)
color::text -- PostgreSQL sexy sexy cast
CAST(color AS TEXT)) -- ANSI SQL standardized vanilla and boring
Run Code Online (Sandbox Code Playgroud)或者,您可以将数组本身构造为类型 varchar[]
array_position(ARRAY['Red','Orange','Yellow','Green','Blue']::varchar[], color);
Run Code Online (Sandbox Code Playgroud)varcharfor colors。即使你坚持不使用ENUMhere(虽然我会),那也应该是text这array_position是一个速记,但我希望它比类似的操作慢得多
CASE
WHEN color='Red' THEN 1::smallint
WHEN color='Orange' THEN 2::smallint
WHEN color='Yellow' THEN 3::smallint
... etc
END;
Run Code Online (Sandbox Code Playgroud)