Дизайн: основная таблица, в которой каждая запись в ней может иметь ноль или более из набора «проверенных» параметров.Мне кажется, что было бы проще поддерживать (добавляя / удаляя параметры), если параметры были частью отдельной таблицы и было выполнено сопоставление между основной таблицей и таблицей параметров.
Цель: представлениекоторая содержит информацию из основной таблицы, а также все параметры, которым была сопоставлена эта строка.Несмотря на то, что последняя информация существует в представлении, должна быть возможность легко извлечь идентификатор опции и ее описание.
Реализация ниже специфична для PostgreSQL, но любая парадигма, которая работает в разных базах данных, представляет интерес.
Оператор select, который делает то, что я хочу:
WITH tmp AS (
SELECT
tmap.MainID AS MainID,
array_agg(temp_options) AS options
FROM tstng.tmap
INNER JOIN (SELECT id, description FROM tstng.toptions ORDER BY description ASC) AS temp_options
ON tmap.OptionID = temp_options.id
GROUP BY tmap.MainID
)
SELECT tmain.id, tmain.contentcolumns, tmp.options
FROM tstng.tmain
INNER JOIN tmp
ON tmain.id = tmp.MainID;
Однако попытка создать представление из этого оператора select приводит к ошибке: столбец "options" содержит запись псевдотипа []
Решение, которое я нашел, состоит в том, чтобы привести массив опций (record []) к текстовому массиву (text [] []);Тем не менее, мне интересно знать, есть ли лучшее решение там.Для справки, инструкция создания:
CREATE OR REPLACE VIEW tstng.vsolution AS
WITH tmp AS (
SELECT
tmap.MainID AS MainID,
array_agg(temp_options) AS options
FROM tstng.tmap
INNER JOIN (SELECT id, description FROM tstng.toptions ORDER BY description ASC) AS temp_options
ON tmap.OptionID = temp_options.id
GROUP BY tmap.MainID
)
SELECT tmain.id, tmain.contentcolumns, CAST(tmp.options AS text[][])
FROM tstng.tmain
INNER JOIN tmp
ON tmain.id = tmp.MainID;
Наконец, DDL в случае, если мое описание было неясным:
CREATE TABLE tstng.tmap (
mainid INTEGER NOT NULL,
optionid INTEGER NOT NULL
);
CREATE TABLE tstng.toptions (
id INTEGER NOT NULL,
description text NOT NULL,
unwanted_column text
);
CREATE TABLE tstng.tmain (
id INTEGER NOT NULL,
contentcolumns text
);
ALTER TABLE tstng.tmain ADD CONSTRAINT main_pkey PRIMARY KEY (id);
ALTER TABLE tstng.toptions ADD CONSTRAINT toptions_pkey PRIMARY KEY (id);
ALTER TABLE tstng.tmap ADD CONSTRAINT tmap_pkey PRIMARY KEY (mainid, optionid);
ALTER TABLE tstng.tmap ADD CONSTRAINT tmap_optionid_fkey FOREIGN KEY (optionid)
REFERENCES tstng.toptions (id);
ALTER TABLE tstng.tmap ADD CONSTRAINT tmap_mainid_fkey FOREIGN KEY (mainid)
REFERENCES tstng.tmain (id);