复制 KDB 中的 table 列

duplicating table columns in KDB

考虑以下代码:

q)tab:flip `items`sales`prices!(`nut`bolt`cam`cog;6 8 0 3;10 20 15 20)
q)tab
items sales prices
------------------
nut   6     10
bolt  8     20
cam   0     15
cog   3     20

我想复制价格栏。我可以这样写一个查询:

q)update prices_copy: prices from tab

我也可以这样写查询:

q)select items, sales, prices, prices_copy: first prices by items from tab

两者都可以。我想知道 "by" 版本如何工作以及编写每个版本的动机。我不禁认为 "by" 版本更符合行数。

您的初始查询理想情况下是您想要的重复列要求。

by 在您的示例中创建列 items 的组,并根据从分组 items 计算的索引折叠 select 查询中的每隔一列。有关 by 的更多信息,请点击此处 - http://code.kx.com/wiki/Reference/select and http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#The_by_Phrase

在您的示例中,列 items 已经是唯一的,因此实际上没有执行折叠成组,但是,by 将从其他列(即列表的列表)创建嵌套列表).使用 first 只会 un-nest items 列,从而将其折叠为普通 (long-typed) 向量。

分组完成后,by 列用作结果的键列,您将通过键列右侧的垂直线看到这一点[s]. select 查询中的所有其他列都放在键的右侧。

by 版本的逻辑巧合地创建了 prices 的副本。但是 by 改变了顺序:

q)ungroup select sales, prices by items from tab
items sales prices
------------------
bolt  8     20    
cam   0     15    
cog   3     20    
nut   6     10    

q)tab
items sales prices
------------------
nut   6     10    
bolt  8     20    
cam   0     15    
cog   3     20    

by 版本有效只是因为 items 是唯一的。对于 tab 具有多个值的 item 例如。 8#tab,查询只为 prices_copy 生成 4 个值。

q)select items, sales, prices, prices_copy: first prices by items from 8#tab
items| items     sales prices prices_copy
-----| ----------------------------------
bolt | bolt bolt 8 8   20 20  20         
cam  | cam  cam  0 0   15 15  15         
cog  | cog  cog  3 3   20 20  20         
nut  | nut  nut  6 6   10 10  10     

简单的 updateupdate by 查询之间存在根本区别。

让我们通过在 table

中添加一个额外的列 brand 来探索它
tab2:flip `items`sales`prices`brand!(`nut`bolt`cam`cog`nut`bolt`cam`cog;6 8 0 3 1 2 3 4;10 20 15 20 30 40 50 60;`b1`b1`b1`b1`b2`b2`b2`b2)

下面将简单地复制该列:

asc update prices_copy: prices from tab2

但是,以下查询正在复制 first item 价格而不考虑品牌,并为同一商品的所有其他品牌更新它。

asc ungroup select sales, prices,brand, prices_copy: first prices by items from tab2
items sales prices brand prices_copy
------------------------------------
bolt  2     40     b2    20
bolt  8     20     b1    20    //b2 price
cam   0     15     b1    15    //b2 price
cam   3     50     b2    15
cog   3     20     b1    20
cog   4     60     b2    20    //b2 price
nut   1     30     b2    10    //b2 price
nut   6     10     b1    10

update by 在您想要复制商品的 max 价格而不考虑品牌或其他一些聚合查询的情况下可能很有用。

asc ungroup select sales, prices,brand, prices_copy: max  prices by items from tab2
items sales prices brand prices_copy
------------------------------------
bolt  2     40     b2    40
bolt  8     20     b1    40    //max price in bolts regardless of the brand
cam   0     15     b1    50
cam   3     50     b2    50
cog   3     20     b1    60
cog   4     60     b2    60
nut   1     30     b2    30
nut   6     10     b1    30