Условное обновление столбца - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть таблица сделок, состоящая из даты, времени, символа, объема, объема аукциона на закрытие.

К сожалению, объем аукциона на закрытие включается в последнюю ячейку таблицы, и усложнить ситуацию может либопроисходят в 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

Я надеялся, что смогу сойти с нижеследующего, но «или», по-видимому, не ведет себя так, как я надеялся, что это произойдет, поскольку он никогда не изменяет второе 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 **

Как и предполагалось, я также попытался:

обновить том: объем-закрытие от t где (время = 15: 59: 00) | время = 12: 59: 00, объем> = значение закрытия

Например, как показано ниже, ВСЕ тома обновляются.Я ожидал, что в 2019.02.01 будут обновлены только 15:59:00 для AAPL и 12:59:00 для BAC, а в 2019.02.02 только 15:59:00 для BAC и 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

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019

Здесь может быть полезно векторное условие ?:

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, и применяет первое условие(удаляя закрывающий элемент), где этот список возвращает значение True, иначе применяется второе условие (оставляет объем как есть).

0 голосов
/ 11 февраля 2019

Ваш пример показывает, что объем может быть больше, чем объем закрытия в оба раза - (12:59:00 15:59:00) для одной и той же даты, пара символов.Вот почему условие 'vol> = closedvol' дает неправильный ответ (который используется вами в вашем примере и также используется в других ответах на ваше сообщение).

Ниже решение будет работать на основе следующих предположений:

  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 на объем и значение закрытия.Я использовал этот способ, чтобы сделать его немного меньше.

0 голосов
/ 11 февраля 2019

В настоящий момент происходит следующее, так как 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

|ведет себя как max в этом случае: 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), который позволит вам добавить дополнительное ограничение, обновляя максимальную запись (времени 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    
...