2013-06-14 4 views
4

Я строю приложение для простой библиотеки. У меня был стол, называемый книгами; среди столбцов:Как вставить в таблицу из другой таблицы путем сопоставления значений?

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 конечных точек для поиска книг по автору понадобится какой-то автор ID:

/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 

и необходимо передать каждую строку книги своему автору через столбец идентификаторов. Я знаю, что мне нужен внешний ключ, но поскольку в таблице книг нет данных, я не могу просто щелкнуть один (все нулевые значения и т. Д.), И в любом случае мне все равно нужно получить все идентификаторы автора и вставить их в правильные строки.

Как я могу вставить правильные author_ids в таблицу книг на основе соответствия значения в существующих столбцах? Я пробовал:

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

Но, предсказуемо, это слишком наивно.

ответ

7

Вы можете присоединиться дополнительные таблицы в UPDATE заявлении, с учетом этого предпочтительной формы:

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

Три причины:

  • Это безопаснее. Ваш запрос будет записывать значение NULL в каждой строке, где не найдено совпадающего автора. Это не имеет значения в вашем случае, но может потенциально привести к потере данных в похожих запросах, где у вас уже есть данные в столбце, который необходимо обновить. Моя альтернатива ничего не делает, если совпадающий автор не найден.

  • Это быстрее. Вышеуказанное для одного. Но также потому, что correlated subqueries, как у вас есть масштаб ужасно. Соединение в таблице обычно быстрее, особенно с несколькими строками.

  • Это чище и легче адаптируется к дополнительным колонкам.

+0

У меня нет необходимости попробовать это сейчас, но он отлично выглядит! Благодаря! – whiterook6

1

whelp, messing around, и я смог ответить на собственный вопрос. Во-первых, это должно быть обновление (duh); второй:

update books set author_id = (select author_id from authors where books.author = authors.author_name); 
Смежные вопросы