【问题标题】:PostgreSQL: update with left outer self join ignoredPostgreSQL:忽略左外自连接的更新
【发布时间】:2012-02-04 17:01:39
【问题描述】:

我想用TRUE 更新列leaf_category,其中该类别不是父类别。它作为一个选择语句工作:

 select 
     c1.id, c1.name, c1.slug, c1.level, c2.parent_id, c2.name, c2.slug, c2.level 
 from
     catalog_category c1 
 left outer join 
     catalog_category c2 on 
     (c1.id = c2.parent_id)
 where 
     c2.parent_id is null;

但是,对应的UPDATE 将所有列设置为TRUE

update catalog_category 
set leaf_category = True
from
    catalog_category c1 
left outer join 
    catalog_category c2 on 
    (c1.id = c2.parent_id)
 where 
     c2.parent_id is null;

这样的UPDATE 可能吗?

【问题讨论】:

    标签: sql postgresql join sql-update


    【解决方案1】:

    您只是缺少一个连接的WHERE 子句:

    UPDATE catalog_category c
    SET    leaf_category = true
    FROM   catalog_category c1 
    LEFT   JOIN catalog_category c2 ON c1.id = c2.parent_id
    WHERE  c.id = c1.id
    AND    c2.parent_id IS NULL;
    

    这个带有NOT EXISTS 的表单可能更快,做同样的事情:

    UPDATE catalog_category c
    SET    leaf_category = true
    WHERE  NOT EXISTS (
        SELECT FROM catalog_category c1
        WHERE  c1.parent_id = c.id
        );
    

    The manual for UPDATE.

    相关:

    【讨论】:

    • @Dems:您可以为要更新的表使用别名,但c1 关系在FROM 子句中。在 PostgreSQL 中,与 MySQL 不同,一次只能更新 一个 表。如果我没记错的话,这对应于 SQL 标准 - 而附加的 FROM 子句是标准的 PostgreSQL 扩展。
    • 谢谢欧文。它起作用了,而且更短了。通过实验我发现在子句中交换 parent_id 和 id 它返回根类别。
    • 第一个语句将不起作用,因为 PostgreSQL 不支持 UPDATE 语句的 FROM 子句中的 JOIN 关键字。您必须在 WHERE 子句中使用“隐式连接”
    • @a_horse_with_no_name:您错了,该语句已经过测试并且有效。几天前我们遇到了同样的事情here
    • 有趣。在手册中肯定看不到。但由于它链接到标准的 FROM 子句,我想这就是它的来源。你生活和学习;)
    猜你喜欢
    • 2018-09-15
    • 2023-03-18
    • 2015-03-20
    • 2011-10-18
    • 2011-06-02
    • 1970-01-01
    • 2017-11-30
    • 2018-10-26
    • 2011-09-14
    相关资源
    最近更新 更多