更新时间点(双时间)table
Updating point-in-time (bitemporal) table
让我们table存储时间点(双时态)数据:
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
table,但前提是它们传达了新信息。不能删除 pit
中的现有记录,也不能删除 updated/overwritten。 IE。我们希望跟踪过时的(如果有的话)值以用于审计或真实性目的。考虑随着时间的推移更新收入估计。
例如,稍后我们可能会收到:
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
请注意 IBM
符号的 "new" 105.22
值输入 pit
与当前时间戳(2015.03.10D15:43:50
在撰写时)。此外,来自 new
的 106.6
值并没有以任何方式更新 pit
中的时间戳,因为我们已经将该值反映在携带较旧时间戳的 pit
中。
如何使用 q
编写相应的 insert
语句?
注意:就其价值而言,pit
将被为简单起见未在此处显示的附加列 source
进行分区。此外,分区将具有 `g#sym
(可能是 `p#sym
)和 `s#dt
属性。
您可以通过以下方式使用'upsert':
参考:http://code.kx.com/q/ref/qsql/#upsert
第 1 步。我在 'new' table 中添加状态列(否则它对于最终 table 中的新行将为空)
q) new:update stamp:`timestamp$.z.z from new
Step 2. 将'new'的那些列作为主键,修改为添加行的条件。在您的情况下,它是除 stamp 列之外的所有列。
q)new:except[cols new;`stamp] xkey new
第 3 步:将 tables 更新为(检查顺序:坑在右侧)
q) pit: 0!new upsert pit
我已经从结果中删除了主键属性。
第 4 步:根据邮票(或任何其他列)对 table 进行排序。
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}
让我们table存储时间点(双时态)数据:
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
table,但前提是它们传达了新信息。不能删除 pit
中的现有记录,也不能删除 updated/overwritten。 IE。我们希望跟踪过时的(如果有的话)值以用于审计或真实性目的。考虑随着时间的推移更新收入估计。
例如,稍后我们可能会收到:
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
请注意 IBM
符号的 "new" 105.22
值输入 pit
与当前时间戳(2015.03.10D15:43:50
在撰写时)。此外,来自 new
的 106.6
值并没有以任何方式更新 pit
中的时间戳,因为我们已经将该值反映在携带较旧时间戳的 pit
中。
如何使用 q
编写相应的 insert
语句?
注意:就其价值而言,pit
将被为简单起见未在此处显示的附加列 source
进行分区。此外,分区将具有 `g#sym
(可能是 `p#sym
)和 `s#dt
属性。
您可以通过以下方式使用'upsert':
参考:http://code.kx.com/q/ref/qsql/#upsert
第 1 步。我在 'new' table 中添加状态列(否则它对于最终 table 中的新行将为空)
q) new:update stamp:`timestamp$.z.z from new
Step 2. 将'new'的那些列作为主键,修改为添加行的条件。在您的情况下,它是除 stamp 列之外的所有列。
q)new:except[cols new;`stamp] xkey new
第 3 步:将 tables 更新为(检查顺序:坑在右侧)
q) pit: 0!new upsert pit
我已经从结果中删除了主键属性。
第 4 步:根据邮票(或任何其他列)对 table 进行排序。
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}