首先按照您的问题中所述的操作顺序,而不使用表格上的`指定要就地的upsert:
`table upsert 行
或再次将其分配给自身,第二个操作将不起作用并抛出类型错误,因为它无法将行插入到空列表中。
若要进一步创建单行表且操作不会引发排名错误,则需要登记列的值:
row:([] x:`val1;y:`val2)
'rank
[6] row:([] x:`val1;y:`val2)
^
row:([] x:enlist `val1;y:enlist `val2)
x y
---------
val1 val2
现在回答你的问题。
为了能够插入或插入具有不同模式的行,@terrylynch 建议的蛮力方法是使用联合联接 (uj),其中
table 需要重新分配给它自己或分配给一个新变量。此操作实质上创建了两个表的超集。
请注意,当第一次连接完成时,空列表的类型会提升为表:
row:([] x:enlist `val1;y:enlist `val2)
table:()
row1:([] x:enlist `val1)
table:table uj row1
table:table uj row
table
x y
---------
val1
val1 val2
应该注意的是,一旦附加列 uj 进入表中,只有符号类型的数据才能插入到该列中,因为该列现在已键入。通常这是一件好事,因为在类型列上运行查询和操作比使用非类型列要快得多。
meta table
c| t f a
-| -----
x| s
y| s
如果您所追求的是能够动态插入不同类型的表数据,则可以创建一个具有无类型列的空表:
table:([] a:0N 0N;b:(();())
table
a b
---
meta table
c| t f a
-| -----
a| j
b|
b列空列表的空记录(sentinal records)的需要是为了保证Q不会把列表打入插入值的类型。
要“就地”插入这个空模式:
`table upsert row1
`table
table
a b
------
()
()
1 `ABB
meta table
c| t f a
-| -----
a| j
b|
请注意,当插入到表中时,如果使用上述指定为动态的模式或其他方式而不是插入单例表,则将行指定为列表/混合列表,其中每个元素表示元素类型匹配的列列类型。
table:([] a:0N 0N;b:(();()))
`table insert (1;`ABB)
,2
`table insert (1;"h")
,3
`table insert (1;3)
,4
table
a b
------
()
()
1 `ABB
1 "h"
1 3
meta table
c| t f a
-| -----
a| j
b|