2014-05-11 315 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