Как заполнить внешние ключи таблицы из других таблиц - PullRequest
5 голосов
/ 25 февраля 2012

У меня есть следующие таблицы, из которых translation пусто, и я пытаюсь заполнить:

translation {
    id
    translated
    language_id
    template_id
}

language {
    id
    langname
    langcode
}

template {
    id
    tplname
    source
    domain
    total
}

Исходные данные для заполнения translation - это временная таблица, которую я заполнил из внешнего файла CSV:

tmp_table {
    id
    translated
    langname
    tplname
    source
    domain
}

Я бы хотел заполнить translation значениями tmp_table. Поле translated можно скопировать напрямую, но я не совсем уверен, как получить правильные language_id (tmp_table.langname можно использовать для определения language.id) и template_id (tmp_table.tplname, tmp_table.source , tmp_table.domain вместе можно использовать для определения template.id).

Это может быть тривиальный вопрос, но я довольно плохо знаком с SQL и не уверен, каким должен быть лучший запрос для заполнения таблицы translation. Есть идеи?

Ответы [ 3 ]

5 голосов
/ 26 февраля 2012

Это можно упростить до:

INSERT INTO translation (id, translated, language_id, template_id)
SELECT tmp.id, tmp.translated, l.id, t.id
FROM   tmp_table tmp
JOIN   language l USING (langname)
JOIN   template t USING (tplname, source, domain)
ORDER  BY tmp.id

Я добавил предложение ORDER BY, которое вам не нужно строго, но некоторые запросы могут получить прибыль, если вы вставите свои кластеризованные данные (или некоторые другие)way.

Если вы хотите избежать потери строк, в которых вы не можете найти подходящую строку в language или template, сделайте его LEFT JOIN вместо JOIN дляобе таблицы (при условии, что language_id и template_id могут быть NULL.

В дополнение к тому, что я уже перечислил под вопросом приквел : если INSERT огромен и составляетБольшая часть целевой таблицы, вероятно, быстрее УДАЛИТЬ все индексы на целевой таблице и впоследствии создавать их заново. Создание индексов с нуля намного быстрее, чем их постепенное обновление для каждогоrow.

Уникальные индексы дополнительно служат ограничениями, поэтому вам придется решить, применять ли правила позже или оставить их на месте.

1 голос
/ 26 февраля 2012

Я не так знаком с PostgreSQL, как другие СУБД, но это должно быть что-то вроде:

   INSERT INTO translation
   SELECT s.id, s.translated, l.id, t.id FROM tmp_table s
   INNER JOIN language l ON (l.langname = s.langname)
   INNER JOIN template t ON (t.tplname = s.tplname)

Похоже, кто-то только что опубликовал в основном тот же ответ с немного другим синтаксисом, но имейте в виду:в соединенных таблицах нет соответствующих имен langname или tplname, строки из tmp_table вообще не будут вставлены, и это не гарантирует, что вы не создадите дубликаты translation.id (поэтому убедитесь, что вы не запускаете его более одного раза).

1 голос
/ 26 февраля 2012
insert into translation (id, translated, language_id, template_id)
select tmp.id, tmp.translated, l.id, t.id
  from tmp_table tmp, language l, template t
 where l.langname = tmp.langname
   and t.tplname = tmp.tplname
   and t.source = tmp.source
   and t.domain = tmp.domain;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...