2017-02-24 55 views
0

考慮下表T在SQL刪除數據庫元素時,調節組合鍵

------------------------------ 
| CountryID | Obs | Event | 
------------------------------ 
| 1   | 1  | 10 |   
| 1   | 2  | 20 | 
| 1   | 3  | 30 | 
| 2   | 1  | 20 | 
| 2   | 2  | 30 | 
| 2   | 3  | 10 | 
| 3   | 1  | 30 | 
| 3   | 2  | 10 | 
| 3   | 3  | 20 | 
------------------------------ 

我想刪除所有行,Event = 20不過,我會再要更新的Obs使他們仍然在增加從1級與1

的差異。例如,如果我跑SELECT * FROM T WHERE Event != 20,我會得到

------------------------------ 
| CountryID | Obs | Event | 
------------------------------ 
| 1   | 1  | 10 |   
| 1   | 3  | 30 | 
| 2   | 2  | 30 | 
| 2   | 3  | 10 | 
| 3   | 1  | 30 | 
| 3   | 2  | 10 | 
------------------------------ 

而是我想

------------------------------ 
| CountryID | Obs | Event | 
------------------------------ 
| 1   | 1  | 10 |   
| 1   | 2  | 30 | 
| 2   | 1  | 30 | 
| 2   | 2  | 10 | 
| 3   | 1  | 30 | 
| 3   | 2  | 10 | 
------------------------------ 

查詢什麼,我需要做到這一點?

+0

(1)用你正在使用的數據庫標記你的問題。 (2)這真的有必要嗎?您可以在需要時計算'Obs',而不是將其存儲在數據庫中。識別行的最佳方式是通過身份/自動遞增/序列列。 –

+0

爲什麼要更新'Obs'?爲什麼不在需要時查詢順序值? – Mureinik

+0

我需要這個的原因是因爲我後來需要一個'T作爲x內聯接作爲y ON(x.CountryID = y.CountryID和x.Obs = y.Obs + 1)'' – rwolst

回答

0

首先,在SQLite中,有一個名爲rowid的僞列,用於唯一標識每一行。你可以做你通過使用相關子查詢想要的東西:

update t 
    set obs = (select count(*) 
       from t t2 
       where t2.countryid = t.countryid and t2.rowid <= t.rowid 
      ); 

這就是說,這是非常低效的,不應該對孩子比其他表的任何運行。如果這是您經常要執行的操作,那麼可以考慮使用比SQLite更強大的數據庫。

+0

'這樣有效選擇'T as x INNER JOIN T as y ON(x.CountryID = y.CountryID AND x.Obs = y.Obs + 1)'其中obs按照我在問題中想要的順序排列。如果是這樣的話,它應該沒問題,因爲那個查詢在我的非嬰兒桌上運行得足夠快。我意識到使用不等式和最小/最大值可以做一些效率很低的事情,但我認爲'obs'的重新排序從長遠來看可能是最有效率的。 – rwolst

+0

@rwolst。 。 。 SQLite是否爲查詢中的每個匹配值或只增加一次值?大多數數據庫只會增加一次值。 –