postgres:(sub)选择并将可选内容组合成一个数组

时间:2018-03-21 15:14:54

标签: sql postgresql

我有以下表结构:

位置----- *媒体---- 1属性-------- * AttributeTranslation

每个位置都附加了n个媒体项,其中包含一个可选属性(文本)和n个与该属性关联的translationa。

我需要将这些数据选择到一个数组中,这样我就能为每个位置获得每种语言的相关中间人。

我现在做的和我得到的是什么:

 SELECT m.location_id, t.language_id,
        array_agg_mult(
          ARRAY[ARRAY[m.sortorder::text, m.filename, t.name]] ORDER BY m.sortorder
        ) as medialist 

 FROM Media m

 LEFT JOIN ATTRIBUTE a ON a.id = m.attribute_id
 LEFT JOIN AttributeTranslation t ON a.id = t.attribute_id

 WHERE m.location_id = ?
 GROUP BY m.location_id, t.language_id

这给出了给定场景的以下结果:当前位置附加了4个图像,只有第一个图像具有包含两个翻译的关联属性:

Location_ID    Language_ID      MEDIALIST
  AT_014           1            {{1,'location_image1.jpg','attribute german'}}
  AT_014           2            {{1,'location_image1.jpg','attribute english'}}
  AT_014                        {{2,'location_image2.jpg',null},{3,'location_image3.jpg',null},{4,'location_image4.jpg',null}}

但我需要的是:

Location_ID    Language_ID      MEDIALIST
  AT_014           1            {{1,'location_image1.jpg','attribute german'},{2,'location_image2.jpg',null},{3,'location_image3.jpg',null},{4,'location_image4.jpg',null}}
  AT_014           2            {{1,'location_image1.jpg','attribute english'},{2,'location_image2.jpg',null},{3,'location_image3.jpg',null},{4,'location_image4.jpg',null}}

这3列是视图的一部分,所以我可以稍后再做:

select * from locationview where location_id = ? and language_id = ?

我怎样才能在这里达到预期的效果?提前谢谢!

简化表格定义:

CREATE TABLE LOCATION (  
  location_id numeric(20) primary key,              
  description text
);

CREATE TABLE MEDIA (  
  media_id numeric(20) primary key,             
  fileName text,
  sortorder smallint,   
  location_id numeric(20) references LOCATION(location_id), 
  attribute_id numeric(20) references ATTRIBUTE(attribute_id)
);

CREATE TABLE ATTRIBUTE (  
  attribute_id numeric(20) primary key,             
  attributetype varchar(100),
);

CREATE TABLE ATTRIBUTETRANSLATION (  
  translation_id numeric(20),               
  language_id smallint,
  name text,
  description text,
  attribute_id numeric(20) references ATTRIBUTE(attribute_id)
);

ALTER TABLE ATTRIBUTETRANSLATION add constraint AT_ID primary key(translation_id, language_id)

1 个答案:

答案 0 :(得分:1)

我不确定我完全理解你的问题,但这是一次尝试。您可以获取查询的输出,并将具有language_id的每一行与language_idNULL的相应行匹配,以便您可以连接medialist阵列。通过使用CTE创建查询的别名,可以采用以下方法:

WITH t AS (
    SELECT m.location_id, t.language_id,
           array_agg(
             ARRAY[ARRAY[m.sortorder::text, m.filename, t.name]] ORDER BY m.sortorder
           ) as medialist 

    FROM Media m

    LEFT JOIN ATTRIBUTE a ON a.attribute_id = m.attribute_id
    LEFT JOIN AttributeTranslation t ON a.attribute_id = t.attribute_id

    WHERE m.location_id = ?
    GROUP BY m.location_id, t.language_id
)
SELECT location_id, t1.language_id, t1.medialist || t2.medialist AS medialist
FROM (SELECT * FROM t WHERE language_id IS NOT NULL) t1
RIGHT OUTER JOIN (SELECT * FROM t WHERE language_id IS NULL) t2 USING (location_id);

我不确定这是否符合您的要求,但希望它会给您一些想法。