qSQL与传统SQL的区别之一就是qSQL具有upsert语义(update and insert),本文主要讲解q中upsert的用法。
首先讲一下upsert与insert的区别。主要有以下四点:
一、对key表进行insert操作时,不可以插入主键值重复的记录,而upsert在插入主键值重复的记录时,会用最新的记录中主键对应的值覆盖原记录的值。
q)t:([name:`Dent`Ann`Bob`Mike] score:88 76 90 71)
q)`t insert(`Dent;77)
'insert
q)`t upsert(`Dent;77)
`t
q)t
name| score
----| -----
Dent| 77
Ann | 76
Bob | 90
Mike| 71
二、upsert可以向分区/分列表等序列化的文件追加记录,而insert不可以。例如:
q)`:d:/kdb/data/test set ([]c1:`a`b;c2:1.1 2.2)
q)`:d:/kdb/data/test upsert(`c;3.3)
q)get `:d:/kdb/data/test
三、insert只能按名称传递,因此只能对全局表进行操作。upsert既可以按名传递又可以按值传递,因此,可以与匿名表或局域表一起使用。
q) ([]c1:`a`b;c2:10 20) upsert (`c;30) / 匿名表
q)f:{t:([]c1:`a`b;c2:10 20);t upsert x} / 局域表
q)f(`c;30)
四、批量插入时,二者写法不同。例如:
q)tnew:([] name:`Sarry`Mickey; score:99 68) / list of collums
q)`t insert tnew
q)t upsert((`Prefect;46);(`Marvin;200)) / list of rows
qSQL中,对key表进行表连接时,lj、ij、ej、pj、uj都具有upsert语义,即当左表和右表具有同名的主键列时,右表的值会覆盖左表。以uj为例:
q)kt1:([k:1 2 3]v1:`a`b`c;v2:10 20 30)
q)kt2:([k:3 4]v2:300 400;v3:3.3 4.4)
q)kt1 uj kt2
k| v1 v2 v3
-| ----------
1| a 10
2| b 20
3| c 300 3.3
4| 400 4.4
更多qSQL的相关内容,请查看《kdb+中文教程》第六章。