2014-05-11 322 views
1

在Oracle SQL中,您可以轻松地根据相关子查询中的NOT EXISTS条件执行更新。这对基于另一个查询或ID列表进行更新很有用。Postgres:与NOT EXISTS相关的子查询

Postgres中的子查询机制是不同的......我如何实现相同的目标? http://sqlfiddle.com/#!1/1dbb8/55

你会怎么做它的Oracle

UPDATE UserInfo a 
SET a.username = 'not found' 
WHERE NOT EXISTS (SELECT 'X' 
       FROM UserOrder b 
       WHERE b.userid = a.userid) 
AND a.userid in (1,2,3); 

Postgres的NOT EXISTS查询:该作品

SELECT u.userid, u.username 
FROM UserInfo AS u 
WHERE NOT EXISTS 
    (SELECT * 
    FROM UserOrder AS o 
    WHERE o.userid = u.userid 
); 

的Postgres NOT EXISTS更新:不工作

UPDATE UserInfo 
SET username = 'not found' 
FROM (SELECT u.userid 
    FROM UserInfo AS u 
    WHERE NOT EXISTS 
     (SELECT * 
     FROM UserOrder AS o 
     WHERE o.userid = u.userid 
     )) em 
WHERE em.userid = UserInfo.userid; 
+0

所以你想更新左反抗连接的左侧?在Pg中,您可以这样做,但不幸的是,它需要在左侧进行自连接,例如, 'update t1 ... from t1 a left outer join ... on ... where t.id = t1.id',因为除了'inner join'之外不支持任何内容(impicit,via'update ...从')更新目标表。 –

+2

给定的解决方案工作。考虑这[更新的小提琴](http://sqlfiddle.com/#!1/1dbb8/75)。 –

回答

2

Sqlfiddle显然会在每次“运行脚本”时重新生成数据库内容。在与更新相同的脚本中运行select。

您从sqlfiddle的Oracle查询几乎可行,但您忘记了别名userid参数。正确的查询:

/* How you would do it on Oracle */ 
UPDATE UserInfo 
SET username = 'not found' 
WHERE NOT EXISTS (SELECT 'X' 
        FROM UserOrder b 
        WHERE b.userid = userinfo.userid); 
2

你为什么要使update比原来的选择更复杂。此代码应在双方的Postgres和Oracle工作:

UPDATE UserInfo ui 
    SET username = 'not found' 
    WHERE NOT EXISTS (SELECT 'X' 
        FROM UserOrder uo 
        WHERE uo.userid = ui.userid 
        ) AND 
     ui.userid in (1,2,3); 

的问题是SET ui.username。 Postgres不允许在set子句中使用表别名(因为您一次只能更新一个表)。

嵌套相关子查询存在一个“问题”。它适用于某些数据库,但不适用于其他数据库。我知道它在SQL Server中起作用,并且它在MySQL和Oracle中不起作用。我想它在Postgres中也不起作用。

+0

这就是我所想的,但是这个SQL更新零行。在SQLfiddle中试试看看我的意思。 – ardochhigh

+1

@ardochhigh。 。 。当我在你的SQL小提琴中尝试它时,它可以工作。你可以在这里看到:http://sqlfiddle.com/#!1/b36ae/1。 –

2
UPDATE UserInfo a 
SET username = 'not found' 
WHERE NOT EXISTS (
     SELECT 'X' 
     FROM UserOrder b 
     WHERE b.userid = a.userid 
    ) 
AND a.userid in (1,2,3) 
    ; 

肯定应该在Postgres工作。

+0

对不起,我不能在SQL小提琴中工作。 – ardochhigh