PostgreSQL插入到多个表中,使用外键从第一次插入到第二次插入
我试图获取一个现有表并创建两个。我有一个PostgreSQL插入到多个表中,使用外键从第一次插入到第二次插入,sql,postgresql,Sql,Postgresql,我试图获取一个现有表并创建两个。我有一个节表,它有一个文件url,现在我需要将它移动到媒体文件表上的url字段中。此外,我还想填充附件表,该表充当的多个:通过(在Rails中),这意味着它跟踪媒体文件id和节id的外键关系 我得到的最接近的结果是: WITH ids AS ( INSERT INTO media_files (url, mimetype) SELECT file_url, 'image/jpeg' FROM sections WHERE file_
节
表,它有一个文件url
,现在我需要将它移动到媒体文件
表上的url
字段中。此外,我还想填充附件表,该表充当的多个:通过(在Rails中),这意味着它跟踪媒体文件id
和节id
的外键关系
我得到的最接近的结果是:
WITH ids AS (
INSERT INTO media_files (url, mimetype)
SELECT file_url, 'image/jpeg'
FROM sections
WHERE file_url IS NOT NULL
RETURNING id AS media_file_id, sections.id AS section_id
)
INSERT INTO attachments (media_file_id, section_id)
SELECT media_file_id, section_id
FROM ids
但我得到了一个错误:
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "sections"
LINE 6: RETURNING id AS media_file_id, sections.id AS sectio...
这是有道理的,但我不确定如何获取部分的id
有没有办法让它工作起来?也许有更好的替代方法
编辑:这里有一个指向的链接,我只能考虑在外部插入中使用附加连接:
WITH ids AS (
INSERT INTO media_files (url, mimetype)
SELECT file_url, 'image/jpeg'
FROM sections
WHERE file_url IS NOT NULL
RETURNING id AS media_file_id, url AS file_url
)
INSERT INTO attachments (media_file_id, section_id)
SELECT ids.media_file_id, s.id
FROM ids
JOIN sections s ON s.file_url = ids.file_url;
SQLFiddle:如果要避免重复出现问题,应在第一个插入中使用DISTINCT
子句。这将使两个部分指向同一个媒体文件,但它应该非常好。(从@a_horse_升级而来,没有名字回答)
一个sqlfiddle会有帮助。@JakubKania:是的,我在想这个。但是,如果在部分
中有重复的文件url
,我想第一次创建一个媒体文件
行,那么复制副本就已经出现在媒体文件
表的原始插入中,显然这不是问题(或者gylaz没有想到),第二次遇到它时,从media\u files
@a\u horse\u中获取现有行,并使用\u no\u名称。如果我们想要一个节-一个媒体文件,并避免重复,我们可以加入第行上的表,这种情况下,DISTINCT
会使我失去具有匹配的文件url的部分的关系。在这种情况下,我仍然希望使用现有的media_文件
id生成一个attachments
行。@gylaz它不会,链接到同一个文件(2,3)的部分指向小提琴中看到的同一个media_文件。所以它的工作原理和你描述的完全一样。
WITH ids AS (
INSERT INTO media_files (url, mimetype)
SELECT DISTINCT file_url, 'image/jpeg'
FROM sections
WHERE file_url IS NOT NULL
RETURNING id AS media_file_id, url AS file_url
)
INSERT INTO attachments (media_file_id, section_id)
SELECT ids.media_file_id, s.id
FROM ids
JOIN sections s ON s.file_url = ids.file_url;