Включение набора строк в столбце представления - PullRequest
1 голос
/ 17 августа 2011

Дизайн: основная таблица, в которой каждая запись в ней может иметь ноль или более из набора «проверенных» параметров.Мне кажется, что было бы проще поддерживать (добавляя / удаляя параметры), если параметры были частью отдельной таблицы и было выполнено сопоставление между основной таблицей и таблицей параметров.

Цель: представлениекоторая содержит информацию из основной таблицы, а также все параметры, которым была сопоставлена ​​эта строка.Несмотря на то, что последняя информация существует в представлении, должна быть возможность легко извлечь идентификатор опции и ее описание.

Реализация ниже специфична для 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);

1 Ответ

1 голос
/ 17 августа 2011

Вы можете создать составной тип, например temp_options_type с:

DROP TYPE IF EXISTS temp_options_type;
CREATE TYPE temp_options_type AS (id integer, description text);

После этого просто приведите temp_options к этому типу в пределах array_agg, поэтому он возвращает temp_options_type[] вместо record[]:

DROP VIEW IF EXISTS tstng.vsolution;
CREATE OR REPLACE VIEW tstng.vsolution AS
    WITH tmp AS
    (
        SELECT
            tmap.MainID AS MainID,
            array_agg(CAST(temp_options AS temp_options_type)) AS options
        FROM
            tstng.tmap INNER JOIN
            (
                SELECT id, description
                FROM tstng.toptions
                ORDER BY description
            ) 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;

Пример результата:

TABLE tstng.vsolution;
 id | contentcolumns |        options        
----+----------------+-----------------------
  1 | aaa            | {"(1,xxx)","(2,yyy)"}
  2 | bbb            | {"(3,zzz)"}
  3 | ccc            | {"(1,xxx)"}
(3 rows)
...