列的条件更新

Conditional update of column

我有一笔交易 table 由日期、时间、代码、交易量、收盘竞价交易量组成。

不幸的是,收盘拍卖量包括在 table 的最后一个箱子中,并且使事情复杂化的可能是在半天内的 15:59:00 或 12:59:00。

有没有办法有条件地更新成交量来移除收盘成交量?

例如,如果它存在,则从 15:59:00 的卷中将其删除,否则将其从 12:59:00 的卷中删除。

例如

t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02;time:12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL;volume:100 25000 26000 0; closingvol: 24000 24000 21000 21000) 

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|25000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000

我想成为

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|15:59:00|AAPL|0|21000

我希望我可以避开下面的问题,但是 "or" 的行为似乎不像我希望的那样,因为它从不修改第二个 12:59:00 条目。

update volume:volume-closingvol from t where (time=15:59:00 | time=12:59:00), volume>=closingvol

**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000 
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-02|12:59:00|AAPL|26000|21000
2019-02-02|15:59:00|AAPL|0|21000

** 更新 1**

按照建议我也试过了:

更新 volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol

例如如下所示,所有卷都已更新。我本来预计在 2019.02.01 只更新 AAPL 的 15:59:00 和 BAC 的 12:59:00,而在 2019.02.02 只更新 BAC 的 15:59:00 和 12:59:00 对于 AAPL,但这修改了 12:59:00 和 15:59:00.

的所有实例
t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)

t:`date`time xasc t

update volume:volume-closingvol from t where (time=15:59:00)|(time=12:59:00), volume>=closingvol


**date**|**time**|**sym**|**volume**|**closingvol**
:-----:|:-----:|:-----:|:-----:|:-----:
2019-02-01|12:59:00|AAPL|100|24000
2019-02-01|12:59:00|BAC|1000|12000
2019-02-01|15:59:00|AAPL|1000|24000
2019-02-01|15:59:00|BAC|0|12000
2019-02-02|12:59:00|AAPL|5000|21000
2019-02-02|12:59:00|BAC|9000|11000
2019-02-02|15:59:00|AAPL|0|21000
2019-02-02|15:59:00|BAC|1000|11000

目前,当 q 从右到左评估 where 子句中的每个约束时,会发生以下情况:

q)time:12:59:00 15:59:00 12:59:00 15:59:00
q)15:59:00 | time=12:59:00
15:59:00 15:59:00 15:59:00 15:59:00

|在这种情况下表现得像最大值: http://code.kx.com/q/ref/arith-integer/#or-maximum

只需更改括号的位置:

q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00, volume>=closingvol
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 15:59:00 AAPL 0      21000  

为次要示例编辑 -

您可以利用 fby (http://code.kx.com/q/ref/qsql/#fby),这将允许您添加额外的约束,为每个 [=25] 更新最大记录(时间 12:59 或 15:59) =]:

q)update volume:volume-closingvol from t where (time=15:59:00)|time=12:59:00,volume>=closingvol,time=(max;time)fby ([]date;sym)
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 12:59:00 BAC  1000   12000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.01 15:59:00 BAC  0      12000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 12:59:00 BAC  20000  11000     
2019.02.02 15:59:00 AAPL 0      21000     
2019.02.02 15:59:00 BAC  1000   11000    

vector conditional ? 在这里可能会有用:

update volume:?[time in 12:59:00 15:59:00;volume-closingvol;volume] from t where vol>=closingvol

第一个参数需要一个布尔列表 - 由 time in 12:59:00 15:59:00 检查创建,并应用第一个条件(删除 closingvol),其中此列表 returns 为真,否则应用第二个条件(离开原样的音量)。

您的示例表明对于同一日期,sym 对,两次交易量都可能大于收盘量 - (12:59:00 15:59:00)。这就是条件 'vol>=closingvol' 给出错误答案的原因(您在您的示例中使用了该答案,也用于您的 post 的其他答案)。

以下解决方案将基于以下假设工作​​:

  1. 所有日期、符号组合都有两个时间 - (12:59:00 15:59:00)。
  2. 数据按时间排序。

即使上述假设在实际场景中不成立,也很容易更改以下查询以根据该假设工作。

  q) t:([]date:2019.02.01 2019.02.01 2019.02.02 2019.02.02 2019.02.02 2019.02.02 2019.02.01 2019.02.01;time:12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00 12:59:00 15:59:00;sym:`AAPL`AAPL`AAPL`AAPL`BAC`BAC`BAC`BAC;volume:100 25000 26000 0 20000 12000 13000 0; closingvol: 24000 24000 21000 21000 11000 11000 12000 12000)

  q) update volume:{?[0=x 1;(x[0]-y[0]),x 1;x[0],x[1]-y[1]]}[volume;closingvol] by date,sym from t where  time in (12:59:00 15:59:00)

或同一查询的其他版本:

  q) update volume: volume-closingvol*(0 1;1 0)0=volume 1 by date,sym from t where  time in (12:59:00 15:59:00)
date       time     sym  volume closingvol
------------------------------------------
2019.02.01 12:59:00 AAPL 100    24000     
2019.02.01 15:59:00 AAPL 1000   24000     
2019.02.02 12:59:00 AAPL 5000   21000     
2019.02.02 15:59:00 AAPL 0      21000     
2019.02.02 12:59:00 BAC  20000  11000     
2019.02.02 15:59:00 BAC  1000   11000     
2019.02.01 12:59:00 BAC  1000   12000     
2019.02.01 15:59:00 BAC  0      12000 

您还可以通过将 x 和 y 替换为 volume 和 closingvol 来避免查询中的 lambda 函数。我用这种方法让它变小了一点。