如何从其他表填充表的外键

时间:2012-02-25 19:53:31

标签: sql database postgresql foreign-keys

我有以下表格,其中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 个答案:

答案 0 :(得分:4)

这可以简化为:

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子句,但是如果您以(或其他)方式插入数据,某些查询可能会获利。

如果您想避免在languagetemplate找不到匹配的行时丢失行,请将其设为 LEFT JOIN 而不是{{ 1}}对于两个表格(假设JOINlanguage_id可以是template_id

除了我已在prequel question下列出的内容之外:如果INSERT很大且占目标表的很大一部分,那么 DROP所有索引可能会更快目标表并在之后重新创建它们。从头开始创建索引很多,然后逐行更新它们。

唯一索引还可用作约束,因此您必须考虑是否稍后执行规则或将其保留在原位。

答案 1 :(得分:1)

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;

答案 2 :(得分:1)

我不像其他RDBMS那样熟悉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的副本(所以请确保你不要多次运行它。)