让我们有一个存储时间点(双时态)数据的表格:
pit:([]dt:`date$();sym:`symbol$();val:`float$();stamp:`timestamp$())
示例数据可能如下所示:
`pit insert (2015.01.05 2015.01.06 2015.01.05;`IBM`IBM`MSFT;105.11 106.6 35.3; 2015.02.01D05:01:25.0 2015.02.01D05:01:25.0 2015.02.01D05:01:25.0)
pit
dt sym val stamp
----------------------------------------------------
2015.01.05 IBM 105.11 2015.02.01D05:01:25.000000000
2015.01.06 IBM 106.6 2015.02.01D05:01:25.000000000
2015.01.05 MSFT 35.3 2015.02.01D05:01:25.000000000
例如,在stamp
时间点,我们为IBM
符号记录的值为105.11,对2015.01.05
有新数据不断涌现,其中一些数据将作为新记录插入pit
表中,但前提是它们传达了新信息。 pit
中的现有记录不得删除,也不得更新/覆盖。即我们希望跟踪过时(如果有)的值以用于审计或真实性目的。考虑一段时间内的盈利预测更新。
例如,稍后我们可能会收到:
new:([]dt:`date$();sym:`symbol$();val:`float$())
`new insert (2015.01.05 2015.01.06;`IBM`IBM;105.22 106.6)
new
dt sym val
---------------------
2015.01.05 IBM 105.22
2015.01.06 IBM 106.6
将new
信息合并到pit
后,后者应如下所示:
pit
dt sym val stamp
----------------------------------------------------
2015.01.05 IBM 105.11 2015.02.01D05:01:25.000000000
2015.01.05 IBM 105.22 2015.03.10D15:43:50.000000000
2015.01.06 IBM 106.6 2015.02.01D05:01:25.000000000
2015.01.05 MSFT 35.3 2015.02.01D05:01:25.000000000
注意" new" 105.22
符号的IBM
值使用当前时间戳(pit
在撰写时)输入2015.03.10D15:43:50
。此外,来自106.6
的{{1}}值未以任何方式更新new
中的时间戳,因为我们已将该值反映在携带较旧时间戳的pit
中。
如何使用pit
撰写相应的insert
语句?
注意:对于它的价值,q
将被此处未显示的其他列pit
分区,以简化起见。此外,分区将具有source
(可能`g#sym
代替)和`p#sym
属性。
答案 0 :(得分:2)
您可以通过以下方式使用'upsert':
参考:http://code.kx.com/q/ref/qsql/#upsert
步骤1.我在'new'表中添加status列(否则对于final table中的新行,它将为null)
q) new:update stamp:`timestamp$.z.z from new
步骤2.将“new”列作为主键,将其修改作为添加行的标准。在你的情况下,它是除邮票列以外的所有列。
q)new:except[cols new;`stamp] xkey new
步骤3:将表格重叠为(检查顺序:坑位于右侧)
q) pit: 0!new upsert pit
我已从结果中删除了主键属性。
步骤4:根据印章(或任何其他栏目)订购表格。
q) pit: `stamp xasc pit
以下是执行所有这些步骤的一项功能:
q) myinsert:{[pit;new] `stamp xasc 0!(except[cols new;`stamp] xkey new:update stamp:`timestamp$.z.z from new) upsert pit}