在 Redshift 更新查询中使用左外连接导致错误:目标表必须是等连接谓词的一部分

Posted

技术标签:

【中文标题】在 Redshift 更新查询中使用左外连接导致错误:目标表必须是等连接谓词的一部分【英文标题】:Using Left Outer Join in Redshift Update Query result in ERROR: Target table must be part of an equijoin predicate 【发布时间】:2021-11-12 04:01:50 【问题描述】:

我有这个查询并运行它导致错误

SQL Error [XX000]: ERROR:
Target table must be part of an equijoin predicate
UPDATE sandbox.f_contribution
SET lpct = NVL(l.percentage, 0)
FROM sandbox.f_contribution AS f
LEFT OUTER JOIN sandbox.f_contribution_last AS l
    ON f.year = l.year AND f.location = l.location AND f.category = l.category
    WHERE f.year = 2020;

docs 说不支持 LEFT OUTER JOIN,它建议“使用一个子查询,将连接条件与更新行的条件明确分开”,所以我尝试修改查询 但同样的错误仍然存​​在:

UPDATE sandbox.f_contribution
SET lpct = NVL(c.percentage, 0)
FROM (
select l.percentage
from sandbox.f_contribution AS f
LEFT OUTER JOIN sandbox.f_contribution_last AS l
    ON f.year = l.year AND f.location = l.location AND f.category = l.category
    ) c WHERE f_contribution.year = 2020;

我应该如何修改相同的查询以在 Redshift 中运行它?

【问题讨论】:

【参考方案1】:

您已经阅读了您的第一个 SQL 中存在的问题。您的第二个是缺少执行 UPDATE 的必要信息,特别是在 WHERE 子句中。

您的子查询生成一组行,其中有一列称为百分比。您的目标表有一个名为 lpct 的列,它被设置为来自子查询的值(如果为 NULL,则设置为零),但是哪个子查询值? UPDATE 假设如何将这些值应用于目标?

我怀疑您需要 WHERE 子句进行一些对齐测试来消除这种混乱。 WHERE 子句基本上就是如何将 FROM 子句中的数据与子查询中的数据连接起来。

猜测你的意图是有风险的,但你可能打算这样做:

UPDATE sandbox.f_contribution
SET    lpct = Nvl(c.percentage, 0)
FROM   sandbox.f_contribution_last AS c
WHERE  f_contribution.year = c.year
       AND f_contribution.location = c.location
       AND f_contribution.category = c.category
       AND f_contribution.year = 2020;

【讨论】:

以上是关于在 Redshift 更新查询中使用左外连接导致错误:目标表必须是等连接谓词的一部分的主要内容,如果未能解决你的问题,请参考以下文章

netezza 左外连接查询性能

当我们在 select 中有 case 语句时,使用左外连接进行 Oracle 更新

如何在 LINQ 中使用左外连接进行 SQL 查询?

使用大表连接更新 Amazon Redshift 中的列

LINQ查询中的左外连接[重复]

使用扩展方法/查询语法在 LINQ 中需要左外连接