我的django app的postgres db中有以下三个表:
publication {
id
title
}
tag {
id
title
}
publication_tags{
id
publication_id
tag_id
}
标签和出版物有多对多的关系。
我想制作一个包含三列的临时表:1)出版物标题,2)出版物ID和3)标签,其中标签是所有标签的列表(如果可能的话,以字符串的形式)在给定的出版物上。
到目前为止,我已经创建了临时表并使用发布ID和发布标题填充它,但我不知道如何将标记放入其中。这就是我到目前为止所做的:
CREATE TEMP TABLE pubtags (pub_id INTEGER, pub_title VARCHAR(50), pub_tags VARCHAR(50))
INSERT INTO pubtags(pub_id, pub_title) SELECT id, title FROM apricot_app_publication
有人可以告诉我如何进行最后一步吗?
答案 0 :(得分:1)
听起来像是string_agg
的工作:
string_agg(expression, delimiter)
输入值连接成一个字符串,用分隔符
分隔
所以这样的事情应该可以解决问题:
insert into pubtags (pub_id, pub_title, pub_tags)
select p.id, p.title, string_agg(t.title, ' ,')
from publication p
join publication_tags pt on (p.id = pt.publication_id)
join tag on (pt.tag_id = t.id)
group by p.id, p.title
您可能想要调整分隔符,我猜测逗号会有意义。
我建议您为pub_tags
使用TEXT而不是VARCHAR,这样您就不必担心溢出pub_tags
长度的字符串聚合。实际上,我建议使用TEXT而不是VARCHAR句点:PostgreSQL会将它们视为相同,除非浪费时间与VARCHAR进行长度检查,因此VARCHAR毫无意义,除非您特别需要有限的长度。
此外,如果您不需要pub_tags
作为字符串,则可以改为使用数组:
CREATE TEMP TABLE pubtags (
pub_id INTEGER,
pub_title TEXT,
pub_tags TEXT[]
)
和array_agg
代替string_agg
:
insert into pubtags (pub_id, pub_title, pub_tags)
select p.id, p.title, array_agg(t.title)
-- as above...
如果需要,使用数组可以更轻松地解压缩标签。