2017-11-03 88 views
0

我有一個表。更新列表值SQLite

ID | VALUE 
id_1 | 1, 2, 3, 4, 5 
id_2 | 6, 7, 8, 9, 10 
id_3 | 11, 12, 13, 14, 15 

而且我通過值+ = 1需要變化值,最終的表應該是這樣的:

ID | VALUE 
id_1 | 2, 3, 4, 5, 6 
id_2 | 7, 8, 9, 10, 11 
id_3 | 12, 13, 14, 15, 16 

我怎麼能這樣做?是否有可能用SQL查詢做到這一點?我應該爲VALUE設置什麼類型的數字或文字?

+2

這是可能的,但它是非常困難的。像這樣的問題就是爲什麼你不想在字符串屬性中存儲列表的完美例證。 – dasblinkenlight

回答

1

正如另一位用戶所指出的,關係數據庫最適合單列存儲在列中的值。也就是說,你可以解析值(按分隔符分割),增加數字,將它們連接到一個字符串並更新該行。您需要爲此創建一個自定義過程。見string functionsstored routines

如果你必須這樣做,你應該聲明該列爲TEXT或VARCHAR;上面顯示的列表不能存儲到數字列中。

完整答案是一些繁重的SQL編程問題。即使您提出了一個可行的解決方案,您的程序只能在一個數據庫上運行的風險也相當可觀。

所以:

更容易的方式是存儲由獨立的ID的二維數據行和位置:

id | pos | value 
------------------ 
id_1 | 1 | 1 
id_1 | 2 | 2 
id_1 | 3 | 3 
... 
id_2 | 1 | 6 
... 

如果有另外的號碼列表等領域進行特定的ID,創建另一個表,如上所示,其中id是主表中的外鍵。

然後更新值僅僅是物質的發行

UPDATE table_name SET value = value + 1 
1

解決方案與Python腳本:

db = sqlite3.connect('Database.db') 
 

 
cursor = db.cursor() 
 
cursor.execute('SELECT Value FROM Problems') 
 

 
all_rows = cursor.fetchall() 
 
for row in all_rows: 
 
    array = row[0].split(',') 
 
    new_string = '' 
 
    for id in array: 
 
     if (id != ''): 
 
      id = int(id) 
 
      id += 1 
 
      id = str(id) 
 
      new_string += id + ',' 
 
    new_string = new_string[:-1] 
 
    cursor.execute('UPDATE Problems SET Value = ? WHERE Value = ?', (new_string, row[0])) 
 
    db.commit() 
 
db.close

1

以下作品的更新:

create table t as 
    select 'id_1' id, '1, 2, 3, 4, 5'  val union 
    select 'id_2' id, '6, 7, 8, 9, 10'  val union 
    select 'id_3' id, '11, 12, 13, 14, 15' val; 

update t set val=(
    with 
    cnt(x) as (select 1 union all select x+1 from cnt limit 999), 
    split as (select id, x from t,cnt where instr(' '||val||',', ' '||x||',')>0) 
    select group_concat(x+1,', ') val from split where id=t.id 
); 

select * from t order by id; 

結果:

id_1|2, 3, 4, 5, 6 
id_2|7, 8, 9, 10, 11 
id_3|12, 13, 14, 15, 16 

它的工作原理,如果你的價值觀是和1之間的整數給出的極限,在這個例子中設置爲999。我在Sqlite版本3.11上成功測試了這個。