debugsqlModerate
ORDER BY gives ERROR: function array_position(text[], character varying) does not exist
Viewed 0 times
errorordervaryingtextfunctioncharacterexistgivesarray_positiondoes
Problem
I have a pretty basic categorical column in a Postgres database that is currently stored as VARCHAR. I can select a count of each with:
I though adding an
But I'm seeing a type error:
What do I need to cast
I though adding an
ORDER BY array_position() would do it:SELECT color, count(*)
FROM research
GROUP BY color
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);But I'm seeing a type error:
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: 98What do I need to cast
color as so I can use the array_position function to order it?Solution
Sample data
You have a table like,
You have an enumerated list of colors. So the easy thing here would be to use an ENUM type
Then
Now it's faster, more efficient, and cleaner. MORE WIN. MORE JOY. Etc.
Is all you'll need.
Array Sort
But, you've got a God-given right to treat this like any other database that doesn't support ENUM types,
I think this is perfectly fine, but I believe there is a limitation here in the implementation,
Is essentially
This means you need to either (speed doesn't matter as both options perform the same)
-
Make the
-
Or, you can construct the array itself as type
Further notes
-
The
You have a table like,
CREATE TABLE research(colors)
AS VALUES ('Blue'), ('Orange'), ('Yellow');ENUM typeYou have an enumerated list of colors. So the easy thing here would be to use an ENUM type
CREATE TYPE colors AS ENUM ('Red','Orange','Yellow','Green','Blue');Then
ALTER TABLE research
ALTER COLUMN colors -- myColorsColumn
SET DATA TYPE colors
USING (colors::colors); -- myColorsColumn::NewTypeNow it's faster, more efficient, and cleaner. MORE WIN. MORE JOY. Etc.
ENUM are stored as 4-byte internally.ORDER BY colorsIs all you'll need.
Array Sort
But, you've got a God-given right to treat this like any other database that doesn't support ENUM types,
ORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);I think this is perfectly fine, but I believe there is a limitation here in the implementation,
ARRAY['foo', 'bar', 'baz']Is essentially
ARRAY['foo', 'bar', 'baz']::textThis means you need to either (speed doesn't matter as both options perform the same)
-
Make the
color column of the native text. This can be done in the call, or you can actually modify the table and should. In PostgreSQL, nothing should be varchar without a limit (since that's just a parallel type for text), and very few things should be varchar with a limit (since there is no advantage)color::text -- PostgreSQL sexy sexy cast
CAST(color AS TEXT)) -- ANSI SQL standardized vanilla and boring-
Or, you can construct the array itself as type
varchar[]array_position(ARRAY['Red','Orange','Yellow','Green','Blue']::varchar[], color);Further notes
- In PostgreSQL, we wouldn't use
varcharforcolors. Even if you insist on not using anENUMhere (though I would), that should betext
-
The
array_position is a shorthand, I expect it to be substantially slower than a similar operation thoughCASE
WHEN color='Red' THEN 1::smallint
WHEN color='Orange' THEN 2::smallint
WHEN color='Yellow' THEN 3::smallint
... etc
END;Code Snippets
CREATE TABLE research(colors)
AS VALUES ('Blue'), ('Orange'), ('Yellow');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::NewTypeORDER BY colorsORDER BY array_position(ARRAY['Red','Orange','Yellow','Green','Blue'], color);Context
StackExchange Database Administrators Q#201837, answer score: 13
Revisions (0)
No revisions yet.