Postgresql

ORDER BY 給出錯誤:函式數組位置(文本, 字元變化) 不存在

  • March 21, 2018

我在 Postgres 數據庫中有一個非常基本的分類列,目前儲存為 VARCHAR。我可以選擇每個計數:

我雖然添加一個ORDER BY array_position()會做到這一點:

SELECT color, count(*)
FROM research
GROUP BY color 
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);

但我看到一個類型錯誤:

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

我需要轉換什麼color才能使用該array_position功能來訂購它?

樣本數據

你有一張像這樣的桌子,

CREATE TABLE research(colors)
 AS VALUES ('Blue'), ('Orange'), ('Yellow');

ENUM類型

您有一個列舉的顏色列表。所以這裡最簡單的事情就是使用ENUM 類型

CREATE TYPE colors AS ENUM ('Red','Orange','Yellow','Green','Blue');

然後

ALTER TABLE research
 ALTER COLUMN colors      -- myColorsColumn
 SET DATA TYPE colors
 USING (colors::colors);  -- myColorsColumn::NewType

現在它更快、更高效、更清潔。更多的勝利。更多歡樂。等ENUM在內部儲存為 4 字節。

ORDER BY colors

就是你所需要的。

數組排序

但是,您擁有上帝賦予的權利,可以像對待任何其他不支持 ENUM 類型的數據庫一樣對待它,

ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);

我認為這很好,但我相信這裡的實現有一個限制,

ARRAY['foo', 'bar', 'baz']

本質上是

ARRAY['foo', 'bar', 'baz']::text

這意味著您需要(速度無關緊要,因為兩個選項執行相同

  1. 製作color原生的專欄text。這可以在呼叫中完成,或者您可以實際修改表和應該。在 PostgreSQL 中,沒有什麼是varchar沒有限制的(因為這只是文本的並行類型),很少有東西應該varchar有限制(因為沒有優勢)
color::text            -- PostgreSQL sexy sexy cast
CAST(color AS TEXT))   -- ANSI SQL standardized vanilla and boring
  1. 或者,您可以將數組本身構造為類型varchar[]
array_position(ARRAY['Red','Orange','Yellow','Green','Blue']::varchar[], color);

補充說明

  • 在 PostgreSQL 中,我們不會使用varcharfor colors。即使您堅持不使用ENUM此處(儘管我願意),那也應該是text
  • array_position是一個速記,我希望它比類似的操作要慢得多
CASE
 WHEN color='Red' THEN 1::smallint
 WHEN color='Orange' THEN 2::smallint
 WHEN color='Yellow' THEN 3::smallint
 ... etc
END;

引用自:https://dba.stackexchange.com/questions/201837