alf*_*oks 11 sql sql-server postgresql sql-update
我是PostgreSQL的新手,试图从SQL Server转换查询.
我有一个表用户,其中包括列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
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其转换为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;
Run Code Online (Sandbox Code Playgroud)
2)我理解为什么它不起作用(它更新所有用户).我只是想不通如何在UPDATE ... SET部分中引用表用户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;
Run Code Online (Sandbox Code Playgroud)
3)以下是有效的,但不使用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;
Run Code Online (Sandbox Code Playgroud)
我可能会选择最后一个解决方案.我只想知道是否可以使用左连接做我想做的事.
Dan*_*ité 17
这是将此更新查询从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
)
Run Code Online (Sandbox Code Playgroud)
ctid是一个伪列,指向行的唯一位置.如果有一个主键,您可以使用表的主键.
问题中的查询#2没有达到您的预期,因为更新的表Users永远不会加入Users uFROM子句中的同一个表.就像在FROM子句中将表名两次放置一样,它们不会被隐式连接或绑定在一起,它们被视为两个独立的行集.
Cli*_*son 13
我认为这是正确的做法 2) 我相信它比做子选择更优化/更有效。
UPDATE Users uOrig
SET bUsrActive = false
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
and uOrig.sUsrClientCode = u.sUsrClientCode;
Run Code Online (Sandbox Code Playgroud)