2011-08-17 5 views
1

디자인 : 기본 테이블에서 각 테이블의 항목 중 0 개 이상에 "선택됨"옵션이있을 수 있습니다. 옵션이 별도의 테이블의 일부이고 기본 테이블과 옵션 테이블간에 매핑이 이루어진 경우 유지 관리 (옵션 추가/제거)가 더 쉬울 것으로 생각됩니다.보기 열에 행 집합 포함

목표 : 기본 테이블의 정보와 해당 행이 매핑 된 모든 옵션을 포함하는보기입니다. 후자의 정보가 뷰에 존재하지만 옵션의 ID와 설명을 쉽게 추출 할 수 있어야합니다.

아래의 구현은 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 문에서보기를 만들려고하면 오류가 발생

내가 찾은 해결책은 텍스트 배열 (text [] [])에 옵션 배열 (record [])을 캐스팅하는 것입니다. 그러나 거기에 더 좋은 해결책이 있는지 알고 싶습니다. 참고로 , 만들기 명령 :

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

당신은 복합 형을 만들 수 있습니다 예를 들어, 와 temp_options_type : 그 후

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

array_agg 내에서 해당 유형에 temp_options 캐스팅, 그래서 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) 
관련 문제