当前位置: 首页 > 面试题库 >

Postgres从左联接更新

康泽宇
2023-03-14
问题内容

我是PostgreSQL的新手,正在尝试从SQL Server转换查询。

我有一个表Users,其中包括bUsrActive,bUsrAdmin和sUsrClientCode列。我想更新用户并设置bUsrActive =
false,如果不存在另一个具有相同sUsrClientCode的用户,其中bUsrAdmin = true和bUsrActive = true。

在SQL Server中,我有此查询

UPDATE u SET u.bUsrActive = 0
FROM Users u
LEFT JOIN Users u2 ON u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = 1 AND u2.bUsrActive = 1
WHERE u.bUsrAdmin = 0 AND u.bUsrActive = 1 AND u2.nkUsr IS NULL

我正在尝试将其转换为postgres。我写了3种方法。

1)我的第一次尝试。显然无法正常工作。

UPDATE Users u
    SET bUsrActive = false
FROM Users u2
WHERE u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = true AND u2.bUsrActive = true
AND u.bUsrAdmin = false AND u.bUsrActive = true AND u2.nkUsr IS NULL;

2)我了解为什么它不起作用(它会更新所有用户)。我只是不知道如何在UPDATE … SET部分中引用表Users u。

UPDATE Users
    SET bUsrActive = false
FROM Users u
LEFT JOIN Users u2 ON u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = true AND u2.bUsrActive = true
WHERE u.bUsrAdmin = false AND u.bUsrActive = true AND u2.nkUsr IS NULL;

3)以下工作正常,但未使用联接。

UPDATE Users
    SET bUsrActive = false
WHERE  NOT EXISTS (
    SELECT 1
    FROM Users u
    WHERE u.sUsrClientCode = Users.sUsrClientCode AND u.bUsrAdmin = true AND u.bUsrActive = true
) AND Users.bUsrAdmin = false AND Users.bUsrActive = true;

我可能会考虑最后一种解决方案。我只是想知道是否可以使用左联接来做我想做的事情。


问题答案:

这是将更新查询从SQL服务器形式转换为PostgreSQL的一种通用方法:

UPDATE Users
 SET bUsrActive = false
WHERE
 ctid IN (
   SELECT u.ctid FROM Users u
      LEFT JOIN Users u2 ON u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = 1 AND u2.bUsrActive = 1
    WHERE u.bUsrAdmin = 0 AND u.bUsrActive = 1 AND u2.nkUsr IS NULL
)

ctid是指向行的唯一位置的伪列。如果表有主键,则可以改用它。

问题中的查询#2不能满足您的期望,因为更新后的表Users永远不会联接到Users uFROM子句中的同一表。就像您在FROM子句中两次放置一个表名一样,它们不会隐式地连接或绑定在一起,它们被视为两组独立的行。



 类似资料:
  • 问题内容: 我正在尝试使用ht的数据更新表tr。两者都有几乎相同的列。因此,为了进行测试,我运行了此查询。 给出129行检查没问题,然后我将更新查询运行为-> 查询成功返回:受影响的行数为4134 有人可以指导我哪里出了问题以及如何解决。 问题答案: 在Postgres中,这有点复杂。但是,我质疑你的逻辑。似乎a是不正确的,因为您正在检查第一个表不是。因此,这 似乎 可以捕获您的逻辑: 该子句是偶

  • 为什么我不能在SELECT部分执行NULL测试?有办法解决这个问题吗?

  • 问题内容: 下载由下载时间,下载时间ID和Buno ID组成。故障由故障代码,下载时间ID,状态和类型组成。下载可能有很多错误,并且可以加入下载时ID。 给定一组故障代码,结果必须包含每个故障代码以及相应的故障计数。如果在下载中未找到故障代码,则必须返回故障计数为零的故障代码。 这个问题似乎需要一个OUTER JOIN,但是在Postgres上却没有像预期的那样工作,因为它似乎没有从LEFT表中返

  • 问题内容: 我们有下面的查询。使用LEFT OUTER联接需要9秒钟才能执行。将LEFT OUTER更改为LEFT INNER可以将执行时间减少到2秒,并且返回 相同 数量的行。由于正在处理dbo.Accepts表中相同数量的行,而不论联接类型如何,为什么外层要花3倍的时间? 问题答案: 返回相同行数的事实是事后事实,查询优化器无法预先知道Accepts中的每一行在Marker中都有匹配的行,可以

  • 我有一个简单的场景TableA、TableB和JoinTable,它连接了TableA和TableB。我想在TableA中为TableA中的每一行存储JoinTable中具有TableAId的记录的计数。我可以正确地选择它如下: 但是,我很难编写更新查询。我想用这个结果更新TableA.JoinCount。

  • 问题内容: 表架构 表名: 行:,, 我的查询模拟将一个文件夹移动到另一个文件夹,并使用IN(?)接受一个数组。 如果不存在具有相同parentId和名称的文件夹,我希望更新仅“移动”文件夹。您在任何普通文件系统下期望的行为。 因此,例如: 将会是一个查询,不检查任何有关parentId和名称的信息…但是如何使左联接起作用。 这是我尝试过的..完全不起作用。 问题答案: 所以,你要只有当目标父文件