我正在构建一个简单的库应用程序。我有一张叫做书的桌子;其中的栏目是:
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);
但可以预见的是,这太天真了。
答案 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)
update books set author_id = (select author_id from authors where books.author = authors.author_name);