Postgres从左联接更新 [英] Postgres update from left join

查看:112
本文介绍了Postgres从左联接更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new in PostgreSQL and trying to convert a query from SQL Server.

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

I have a table Users with, among others, the columns bUsrActive, bUsrAdmin and sUsrClientCode. I want to update Users and set bUsrActive = false if there does not exist a another user with the same sUsrClientCode where bUsrAdmin = true and bUsrActive = true.

在SQL Server中拥有此查询

In SQL Server I have this query

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种方法。

I'm trying to convert this to postgres. I wrote 3 approaches.

1)我的第一次尝试。

1) My first attempt. Obviously not working.

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。

2) I understand why it's not working (it updates all users). I just can't figure out how can I reference table Users u in the UPDATE ... SET part.

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)以下工作正常,但未使用join。

3) The following is working, but not using join.

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;

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

I'll probably go with the last solution. I just wanted to know if it's possible to do what I want using a left join.

推荐答案

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

Here's a generic way to transform this update query from SQL-server form to 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 是指向行的唯一位置。您可以使用表的主键(如果有)。

ctid is a pseudo-column that points to the unique location of a row. You could use instead the primary key of the table if it had one.

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

The query #2 from the question doesn't do what you expect because the updated table Users is never joined to the same table Users u in the FROM clause. Just as when you put a table name twice in a FROM clause, they don't get implicitly joined or bound together, they are considered as two independant sets of rows.

这篇关于Postgres从左联接更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆