我有以下表格,其中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
表的最佳查询是什么。有任何想法吗?
答案 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
子句,但是如果您以(或其他)方式插入数据,某些查询可能会获利。
如果您想避免在language
或template
找不到匹配的行时丢失行,请将其设为 LEFT JOIN
而不是{{ 1}}对于两个表格(假设JOIN
和language_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的副本(所以请确保你不要多次运行它。)