update

update 语句用于更新数据表中的记录。

New in version 1.30.6: 支持 DFS 表(包括维度表和分区表)的更新

update 语句不仅支持更新内存表,也支持更新没有正在写入数据的 DFS 表(分布式表与维度表)。请注意,当更新分布式表时,系统把要更新记录所在的分区整体更新;更新维度表时,系统将该表整体更新。因此更新 DFS 表仅适用于低频更新任务,例如分钟级更新任务,不适用于高频更新任务,例如毫秒级更新任务。

更新采取了多版本的方式,并且支持事务。系统会创建一个新的版本以存储新的数据。提交事务之前,其他 SQL 语句仍然访问旧版本的数据。若更新涉及多个分区,只要其中某一个分区更新失败,系统会回滚所有分区的修改。

请注意,update 语句无法改变列的数据类型。

语法

update
    [table_name]
    set col1=X1, [col2=X2,...]
    [from table_joiner(table_names)]
    [where condition(s)]
    [context by col_name(s)]

例子

例 1:更新内存表

sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);

t1;

timestamp

sym

qty

price

09:34:07

C

2200

49.6

09:36:42

MS

1900

29.46

09:36:51

MS

2100

29.52

09:36:59

MS

3200

30.02

09:32:47

IBM

6800

174.97

09:35:26

IBM

5400

175.23

09:34:16

C

1300

50.76

09:34:26

C

2500

50.32

09:38:12

C

8800

51.29

使用 update 语句创建新的列,该列的值为空。

update t1 set vol=long();

t1;

timestamp

sym

qty

price

vol

09:34:07

C

2200

49.6

09:36:42

MS

1900

29.46

09:36:51

MS

2100

29.52

09:36:59

MS

3200

30.02

09:32:47

IBM

6800

174.97

09:35:26

IBM

5400

175.23

09:34:16

C

1300

50.76

09:34:26

C

2500

50.32

09:38:12

C

8800

51.29

$ t1.drop!(`vol);
// 将 t1 还原到初始状态

更新 trades 表,将股票符号为 C 的记录的 price 列加 $0.5 以及 qty 列减 50。

update t1 set price=price+0.5, qty=qty-50 where sym=`C;
t1;

timestamp

sym

qty

price

09:34:07

C

2150

50.1

09:36:42

MS

1900

29.46

09:36:51

MS

2100

29.52

09:36:59

MS

3200

30.02

09:32:47

IBM

6800

174.97

09:35:26

IBM

5400

175.23

09:34:16

C

1250

51.26

09:34:26

C

2450

50.82

09:38:12

C

8750

51.79

update t1 set price=price-0.5, qty=qty+50 where sym=`C;
//  t1 还原到初始状态

使用 context by 更新一张表。context by 可以用来做分组调整,而 contextby 不可。下例首先使用 context by 计算每只股票的平均价格,然后将每个记录的原始价格减去平均价格。

update t1 set price=price-avg(price) context by sym;
t1;

timestamp

sym

qty

price

09:34:07

C

2150

-0.8925

09:36:42

MS

1900

-0.206667

09:36:51

MS

2100

-0.146667

09:36:59

MS

3200

0.353333

09:32:47

IBM

6800

-0.13

09:35:26

IBM

5400

0.13

09:34:16

C

1250

0.2675

09:34:26

C

2450

-0.1725

09:38:12

C

8750

0.7975

使用表连接来更新表。

$ item = table(1..10 as id, 10+rand(100,10) as qty, 1.0+rand(10.0,10) as price)
$ promotion = table(1..10 as id, rand(0b 1b, 10) as flag, 0.5+rand(0.4,10) as discount);
$ item;

id

qty

price

1

23

7.839664

2

44

7.635988

3

76

5.378054

4

91

8.078173

5

11

10.316152

6

58

9.510634

7

90

1.643082

8

68

5.787797

9

52

7.53352

10

62

6.222249

$ promotion;

id

flag

discount

1

0

0.650346

2

0

0.697081

3

0

0.774207

4

1

0.819562

5

0

0.710393

6

0

0.728223

7

1

0.602512

8

0

0.71226

9

1

0.606631

10

0

0.765697

update item set price = price*discount from ej(item, promotion, `id) where flag=1;
item;

id

qty

price

1

23

7.839664

2

44

7.635988

3

76

5.378054

4

91

6.620566

5

11

10.316152

6

58

9.510634

7

90

0.989976

8

68

5.787797

9

52

4.570069

10

62

6.222249

例 2. 更新分布式表

$ login(`admin, `123456)
$ n=1000000
$ ID=rand(10, n)
$ x=rand(1.0, n)
$ t=table(ID, x)
$ db=database("dfs://rangedb123", RANGE,  0 5 10)
$ pt=db.createPartitionedTable(t, `pt, `ID)
$ pt.append!(t)
$ pt=loadTable("dfs://rangedb123", `pt)
$ select avg(x) from pt;
0.4999

$ update pt set x=x+1;

$ pt=loadTable("dfs://rangedb123", `pt)
$ select avg(x) from pt;
1.4999