KDB优雅地选择列上具有最大值的行

时间:2018-06-21 20:54:49

标签: kdb

我有此股票价格表(此处为简化版):

+----------+--------+-------+
|   Time   | Ticker | Price |
+----------+--------+-------+
| 10:00:00 | A      |     5 |
| 10:00:01 | A      |     6 |
| 10:00:00 | B      |     3 |
+----------+--------+-------+

我想按时间最长的代码选择行组,例如

+----------+--------+-------+
|   Time   | Ticker | Price |
+----------+--------+-------+
| 10:00:01 | A      |     6 |
| 10:00:00 | B      |     3 |
+----------+--------+-------+

我知道如何在SQL中执行此操作,可以找到类似的问题here,但我不知道如何在KDB中进行优雅的操作。

我有一个选择两次的解决方案:

select first Time, first Ticker, first Price by Ticker from (`Time xdesc select Time, Ticker, Price from table where date=2018.06.21)

还有更多干净的解决方案吗?

2 个答案:

答案 0 :(得分:8)

只要您要进行涉及by的双重选择,就可以改而使用fby

q)t:([]time:10:00:00 10:00:01 10:00:00;ticker:`A`A`B;price:5 6 3)
q)
q)select from t where time=(max;time) fby ticker
time     ticker price
---------------------
10:00:01 A      6
10:00:00 B      3

Kdb还提供了获取select by(没有指定列)时获取最近记录的快捷方式,但是这种方法不那么通用或可定制

q)select by ticker from t
ticker| time     price
------| --------------
A     | 10:00:01 6
B     | 10:00:00 3

答案 1 :(得分:1)

还要注意的另一件事是,select by如果数据排序不正确,可能会导致错误的结果。 例如

select by ticker from reverse[t]
ticker| time     price
------| --------------
A     | 10:00:00 5 //wrong result
B     | 10:00:00 3

fby可以得到正确的结果,而与顺序无关:

select from (reverse  t) where time=(max;time) fby ticker
time     ticker price
---------------------
10:00:00 B      3
10:00:01 A      6