【问题标题】:KDB/q: How to update a table with row containing disparate columns?KDB/q:如何更新包含不同列的行的表?
【发布时间】:2026-01-27 19:45:01
【问题描述】:

我正在尝试使用辅助表/行 (B) 更新表 (A),如下所示:

table:()
row:([]x:`val1;)

table upsert row
table insert row

当所有后续行都具有相同的架构时,该方法有效。 但是,我试图解释的一个极端情况与后续行何时可能具有不同的模式有关,即:

row:([]x:`val1;y:`val2)

上面会引发mismatch 错误,这是意料之中的。 如何修改上述插入/更新插入逻辑以应对具有不同架构的更新的出现?

【问题讨论】:

    标签: kdb


    【解决方案1】:

    首先按照您的问题中所述的操作顺序,而不使用表格上的`指定要就地的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|
    

    【讨论】:

    • @Brad 将不得不在这里评论我自己的帖子,因为我还没有足够的声誉。但是你有没有想过将你的表格翻转成字典并通过赋值来扩展它们。如果我理解您的编辑错误。您尝试插入的数据样本会有所帮助,我会重新创建问题并可能提供更好的答案
    【解决方案2】:

    你可以使用联合加入

    q)table uj row
    x    y
    ---------
    val1
    val1 val2
    

    在此处记录:https://code.kx.com/v2/ref/uj/

    【讨论】: