2014-06-12 41 views
2

我有兩個表。讓我們打電話給一個items。其中的列是一些獨特的ID,位置和舊位置。 如果它有一箇舊位置,它目前從position_old移動到position。如果它有一個-舊的位置 它不動。每個位置可以有多個項目。更新一些未在另一個表中使用的列

第二張表(position)是針對職位的。其中的列是唯一的ID和狀態。

我需要更新的位置表具有狀態100和沒有項目被移動到它 (position = position_id AND position_old != '-'),並沒有從項目它(position_old = position_id)移動所有的行。

+---------+----------+--------------+ 
| item_id | position | position_old | 
+---------+----------+--------------+ 
|  1 | 0001  | -   | 
|  2 | 0001  | 0002   | 
+---------+----------+--------------+ 

+-------------+--------+ 
| position_id | status | 
+-------------+--------+ 
| 0001  |  0 | 
| 0002  | 100 | 
+-------------+--------+ 

我得到了一些解決方案,但我不認爲這將是最好的一個:

UPDATE Position 
SET status = 0 
WHERE status = 100 
AND position_id NOT IN (
    SELECT DISTINCT position_old FROM Items WHERE position_old != '-' 
    UNION 
    SELECT DISTINCT position FROM Items WHERE position_old != '-' 
) 

那麼,有沒有更好的方法呢?只要信息 它的Oracle 11.2.0.4數據庫,如果你建議與連接的東西,它應該是蹩腳的舊語法,只要大家 這裏是與它合作,不願意學習新的標準。

回答

0

我認爲更有效的將是:

UPDATE Position out_pos 
SET status = 0 
WHERE status = 100 
AND not exists (
SELECT 1 FROM Items sub_pos WHERE 
sub_pos.position_old != '-' and 
( 
    sub_pos.position = out_pos.position_id 
    OR 
    sub_pos.position_old = out_pos.position_id 
) 
) 
0

你的說法是正確的,但我寧願把它與寫「不存在」,以配合自然語言形式:

UPDATE Position 
SET status = 0 
WHERE 
    -- which have status 100: 
    status = 100 
    AND 
    -- have no item which is moving to it: 
    NOT EXISTS (SELECT * FROM items WHERE position = position_id AND position_old <> '-') 
    AND 
    -- no item moving from it: 
    NOT EXISTS (SELECT * FROM items WHERE position_old = position_id) 

由於爲了提高效率,執行語句和查看執行計劃是不可替代的。根據索引的存在,表格的基數和條件的選擇性(以及更多......),Oracle會很高興地將「EXISTS」重寫爲「IN」等等。

看起來很有可能items上的索引position_old, position(按此順序)會很有幫助。

相關問題