Недавно я заново открыл пользовательские типы и массивы Postgres, которые заставили меня почувствовать, что Postgres был NoSQL (не только SQL) задолго до того, как термин стал популярным.
Необходимо сделать выбормассив столбца значений перечисления для отображения всех значений перечисления и флаг, если столбец массива перечисления включает значение перечисления или не имеет правильной сортировки (сначала сортировка по примененным значениям перечисления по столбцу, а затем по порядку значений перечисления, если значение перечисления не было включено встолбец)
Пример DDL:
-- available website settings enum:
CREATE TYPE website_menu_extras_type AS ENUM ( 'logo', 'emails', 'locations', 'phones', 'search' );
-- this type represents if website setting is enabled or not (the setting is treated as enabled if it's included to a website's column `menu_extras` of type `website_menu_extras_type[]`):
CREATE TYPE website_menu_extras_with_defaults AS ( menu_extra website_menu_extras_type, is_enabled BOOLEAN );
-- website table which contains applied `website_menu_extras_type` values as array:
CREATE TABLE website ( ID serial PRIMARY KEY, menu_extras website_menu_extras_type [] );
-- insert some values:
INSERT INTO website ( menu_extras )
VALUES
( ARRAY [ 'logo', 'emails' ]:: website_menu_extras_type [] );
-- select `menu_extras` as applied values
-- and `menu_extras_with_defaults` which is an array
-- of website_menu_extras_with_defaults having
-- all values of `website_menu_extras_type` enum
-- and `is_enabled` set to true if `menu_extras` includes enum value
-- and `is_enabled` set to false if `menu_extras` does not include enum value
-- `menu_extras_with_defaults` should be sorted by `menu_extras` order
-- and then by `website_menu_extras_type` enum order if `menu_extras` didn't include the enum value
SELECT
id, menu_extras, menu_extras as menu_extras_with_defaults
FROM
website;
Может быть огромное количество записей на веб-сайте, будет в основном чтение, и в будущем будет расширен список настроек, поэтомунастройки, «включенные» в запись веб-сайта, выглядят гораздо лучшим решением, чем использование таблицы «многие ко многим».
Я начал с UDF (например, он не будет работать так, как ожидалось), например:
CREATE FUNCTION website_menu_extras_with_defaults ( website website ) RETURNS website_menu_extras_with_defaults[] AS $$
WITH
all_enum_values
AS
(
SELECT UNNEST
(
enum_range ( NULL
:: website_menu_extras_type )) AS val
),
all_enum_values1 AS
(
SELECT UNNEST
(
enum_range ( NULL
:: website_menu_extras_type )) AS val
)
-- select * from x1
SELECT
array[( val, FALSE ), (val, TRUE)]
:: website_menu_extras_with_defaults []
FROM
all_enum_values
-- where val in (website).menu_extras
$$ LANGUAGE SQL STABLE;
, который мне не удалось сделать так, как ожидалось.
Как бы вы получили правильное значение menu_extras_with_defaults
в этом случае?се