今天早上我问this非常相似的问题,答案很精彩。
然而,在审阅了该剧之后,我发现我的实际问题是稍微比我在该问题中描述的更复杂。基本上,我有3个Postgres表:
[myschema].[animals]
--------------------
animal_id
animal_attrib_type_id (foreign key to [myschema].[animal_attrib_types])
animal_attrib_value_id (foreign key to [myschema].[animal_attrib_values])
[myschema].[animal_attrib_types]
--------------------------------
animal_attrib_type_id
animal_attrib_type_name
[myschema].[animal_attrib_values]
--------------------------------
animal_attrib_value_id
animal_attrib_value_name
所以,我可能会有animal
这样的记录:
[myschema].[animals]
--------------------
animal_id = 458
animal_attrib_type_id = 38
animal_attrib_value_id = 23
相应的animal_attrib_type
(id = 38)具有以下值:
[myschema].[animal_attrib_types]
--------------------------------
animal_attrib_type_id = 38
animal_attrib_type_name = 'animals.should-make-noise'
相应的animal_attrib_value
(id = 23)具有以下值:
[myschema].[animal_attrib_values]
--------------------------------
animal_attrib_type_id = 23
animal_attrib_type_name = 'true'
因此,相同的animal
记录可以有多个类型/值对。在这种情况下,动物的animal_attrib_type_name
“animals.should-make-noise
”对应animal_attrib_value_name
“true
”。
在运行时,我只有animal_id
(即458)和animal_attrib_type_id
(即38)。我需要能够仅查找与给定animal_attrib_value_name
和animal_id
相对应的animal_attrib_type_id
相应的{{1}},然后将其值更新为某些静态文本('true'或'false') ;所有这些都来自同一个UPDATE语句。
上面提到的问题的答案对于我说的问题是正确的,但由于同一个动物有0 +类型/值组合,我实际上需要一个稍微不同的SQL语句。提前谢谢!
答案 0 :(得分:7)
利用FROM
clause in the PostgreSQL UPDATE
command。这通常更清洁,更快。
UPDATE animal_attrib_values av
SET animal_attrib_value_name = 'true'
FROM animals a
WHERE a.animal_id = 458
AND a.animal_attrib_type_id = 38
AND a.animal_attrib_value_id = av.animal_attrib_value_id;
由于我们已经知道animal_attrib_type_id
,因此我们根本不需要包含第三个表animal_attrib_types
。如果需要,我们可以另外加入......
此外,请勿对SET
中的UPDATE
项进行表格限定。这是一个语法错误。我引用manual on said page:
不要在目标规范中包含表的名称 列 - 例如,
UPDATE tab SET tab.col = 1
无效。
大胆强调我的。
答案 1 :(得分:1)
以下SQL应该按照您的要求执行:
UPDATE animal_attrib_values aav
SET animal_attrib_value_name= 'true'
WHERE aav.animal_attrib_value_id = (
SELECT a.animal_attrib_value_id
FROM animals a
WHERE a.animal_id = 458
AND a.animal_attrib_type_id = 38
)
;