如何通过匹配值从另一个表插入表中?

时间:2013-06-14 23:23:13

标签: sql postgresql sql-update

我正在构建一个简单的库应用程序。我有一张叫做书的桌子;其中的栏目是:

books:
book_id   | integer | not null default nextval('books_book_id_seq'::regclass)
title     | text    | not null
author    | text    | not null default 'unknown'::text

我没有计划与作者做过任何特别的事情,因为我关心他们的都是他们的名字(所以没有连接表,没有作者表等)但是,我发现用于查找书籍的API端点作者将需要某种作者身份:

/browse/author/12345

而不是

/browse/author/Arthur%20C%20Clarke (or whatever)

我为作者创建了一个单独的表:

authors:
author_id   | integer | not null default nextval('authors_author_id_seq'::regclass)
author_name | text    | not null

并且需要通过id列将每个书行引用给作者。我知道我需要一个外键,但由于书籍表中没有数据我不能简单地打一个(所有空值等),无论如何我仍然需要获取所有作者id并将它们插入到正确的行。

如何根据匹配现有列中的值,将正确的author_ids插入books表?我试过了:

insert into books (author_id) select author_id from authors where (books.author == authors.author_name);

但可以预见的是,这太天真了。

2 个答案:

答案 0 :(得分:9)

您可以在UPDATE语句中加入其他表格,从而获得以下优选形式:

UPDATE books b
SET    author_id = a.author_id
FROM   authors a
WHERE  b.author = a.author_name;

三个原因:

  • 更安全。您的查询将在未找到匹配作者的每一行中写入NULL值。在您的情况下,这并不重要,但可能会导致类似查询中的数据丢失,您已在列中更新数据。 如果找不到匹配的作者,我的选择无效。

  • 速度更快。以上为一。但也因为correlated subqueries喜欢你的规模非常严重。加入表格通常更快,特别是有多行。

  • 它更干净,更容易适应其他色谱柱。

答案 1 :(得分:1)

哎呀,搞砸了,我已经设法回答了我自己的问题。首先,它应该是一个更新(duh);第二:

update books set author_id = (select author_id from authors where books.author = authors.author_name);