web-dev-qa-db-ja.com

ORDER BYはエラーを出します:関数array_position(text []、文字が変化する)は存在しません

現在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);

しかし、私はタイプエラーを見ています:

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

array_position関数を使用して注文できるように、colorをキャストするために何が必要ですか?

7
Amanda

サンプルデータ

次のようなテーブルがあります

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

ENUMタイプ

色の列挙リストがあります。したがって、ここでの簡単なことは ENUM type を使用することです。

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. ネイティブcolortext列を作成します。これは呼び出しで行うことも、実際にテーブルを変更することもできます。 PostgreSQLでは、何も制限なしでvarcharにすることはできません(これはテキストの単なる並列型であるため)、制限付きのvarcharはほとんどありません(利点がないため)。

    color::text            -- PostgreSQL sexy sexy cast
    CAST(color AS TEXT))   -- ANSI SQL standardized Vanilla and boring
    
  2. または、配列自体をタイプvarchar[]として構築できます。

    array_position(ARRAY['Red','Orange','Yellow','Green','Blue']::varchar[], color);
    

その他のメモ

  • PostgreSQLでは、varcharcolorsを使用しません。ここで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;
    
9
Evan Carroll