回答

收藏

Postgres更新左联接

技术问答 技术问答 357 人阅读 | 0 人回复 | 2023-09-14

我是PostgreSQL新手,正在尝试从SQL Server转换查询。6 Z; a) t# N! B! \4 e, K
我有一个表Users,其中包括bUsrActive,bUsrAdmin和sUsrClientCode列。我想更新用户并设置它。bUsrActive =
3 z7 z9 B4 w; B( c. t/ c+ R# U' yfalse,如果没有另一个,它是一样的sUsrClientCode用户,其中bUsrAdmin = true和bUsrActive = true。
9 U3 ^- h; M- P, ]6 e在SQL Server我有这个查询
8 U6 V. X$ n8 P) X: q) t4 @UPDATE u SET u.bUsrActive = 0FROM Users uLEFT JOIN Users u2 ON u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = 1 AND u2.bUsrActive = 1WHERE u.bUsrAdmin = 0 AND u.bUsrActive = 1 AND u2.nkUsr IS NULL我试着把它转换成postgres。我写了三种方法。0 k- W7 ^: V5 V6 p/ x
1)我的第一次尝试。显然不能正常工作。
6 }: g6 W1 ]7 @5 V  D* J. T5 BUPDATE Users u    SET bUsrActive = falseFROM Users u2WHERE u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = true AND u2.bUsrActive = trueAND u.bUsrAdmin = false AND u.bUsrActive = true AND u2.nkUsr IS NULL;2)我知道为什么它不起作用(它会更新所有用户)。我只是不知道该怎么办。UPDATE … SET部分引用表Users u。
' ?+ t; \% s( s# n9 B( k5 GUPDATE Users    SET bUsrActive = falseFROM Users uLEFT JOIN Users u2 ON u.sUsrClientCode = u2.sUsrClientCode AND u2.bUsrAdmin = true AND u2.bUsrActive = trueWHERE u.bUsrAdmin = false AND u.bUsrActive = true AND u2.nkUsr IS NULL;3)以下工作正常,但未使用连接。
. ^5 Z, B1 h4 h0 _UPDATE Users    SET bUsrActive = falseWHERE  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;我可能会考虑最后一个解决方案。我只是想知道左连接是否可以用来做我想做的事情。
  O1 ^5 v% \3 A& O                                                                & O! v. K% c$ P2 c6 O
    解决方案:                                                               
4 L& \' a( u9 h  ^                                                                这是更新查询从SQL将服务器形式转换为PostgreSQL一般方法:+ r6 K' x# \, q4 {  N/ T
UPDATE Users SET bUsrActive = falseWHERE 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伪列是指向行的唯一位置。若表有主键,则可改用。' ~/ n# B0 Z" J# s  V; O7 m0 O2 a
问题中的查询#2不能满足你的期望,因为更新后的表Users永远不会联系UsersuFROM句子中的同一表。就像你在FROM在句子中两次放置一个表名,它们不会隐藏地连接或绑定在一起,它们被视为两组独立的行。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则