Q 语言 - 查询
q 中的查询更短、更简单,并且扩展了 sql 的功能。 主要查询表达式是"选择表达式",它以最简单的形式提取子表,但也可以创建新列。
Select 表达式的一般形式如下 −
Select columns by columns from table where conditions
**注意 − by & where短语是可选的,只有"from表达式"是强制性的。
一般来说,语法是 −
select [a] [by b] from t [where c] update [a] [by b] from t [where c]
q 表达式的语法看起来与 SQL 非常相似,但是 q 表达式简单而强大。 上述 q 表达式的等效 SQL 表达式如下 −
select [b] [a] from t [where c] [group by b order by b] update t set [a] [where c]
所有子句都在列上执行,因此 q 可以利用顺序。 由于 Sql 查询不是基于顺序的,因此它们无法利用这一优势。
q 关系查询的大小通常比相应的 SQL 要小得多。 有序查询和函数查询可以完成 SQL 中难以完成的任务。
在历史数据库中,where子句的顺序非常重要,因为它会影响查询的性能。 partition(分区)变量(日期/月/日)始终排在第一位,然后是排序和索引列(通常是 sym 列)。
例如,
select from table where date in d, sym in s
更快
select from table where sym in s, date in d
基本查询
让我们在记事本中编写一个查询脚本(如下),保存(为*.q),然后加载它。
sym:asc`AIG`CITI`CSCO`IBM`MSFT; ex:"NASDAQ" dst:`$":c:/q/test/data/"; /database destination @[dst;`sym;:;sym]; n:1000000; trade:([]sym:n?`sym;time:10:30:00.0+til n;price:n?3.3e;size:n?9;ex:n?ex); quote:([]sym:n?`sym;time:10:30:00.0+til n;bid:n?3.3e;ask:n?3.3e;bsize:n?9;asize:n?9;ex:n?ex); {@[;`sym;`p#]`sym xasc x}each`trade`quote; d:2014.08.07 2014.08.08 2014.08.09 2014.08.10 2014.08.11; /Date vector can also be changed by the user dt:{[d;t].[dst;(`$string d;t;`);:;value t]}; d dt/:\:`trade`quote; Note: Once you run this query, two folders .i.e. "test" and "data" will be created under "c:/q/", and date partition data can be seen inside data folder.
带约束的查询
* 表示 HDB 查询
选择所有 IBM 交易
select from trade where sym in `IBM
*选择某一天的所有 IBM 交易
thisday: 2014.08.11 select from trade where date=thisday,sym=`IBM
选择价格 > 100 的所有 IBM 交易
select from trade where sym=`IBM, price > 100.0
选择价格小于或等于 100 的所有 IBM 交易
select from trade where sym=`IBM,not price > 100.0
*选择特定日期上午 10.30 到 10.40 之间的所有 IBM 交易
thisday: 2014.08.11 select from trade where date = thisday, sym = `IBM, time > 10:30:00.000,time < 10:40:00.000
选择按价格升序选择所有 IBM 交易
`price xasc select from trade where sym =`IBM
*选择按价格降序选择特定时间范围内的所有 IBM 交易
`price xdesc select from trade where date within 2014.08.07 2014.08.11, sym =`IBM
复合排序 − 按 sym 升序排序,然后按价格降序排序
`sym xasc `price xdesc select from trade where date = 2014.08.07,size = 5
选择所有 IBM 或 MSFT 交易
select from trade where sym in `IBM`MSFT
*按升序计算一定时间范围内所有符号的数量
`numsym xasc select numsym: count i by sym from trade where date within 2014.08.07 2014.08.11
*按降序计算一定时间范围内所有符号的数量
`numsym xdesc select numsym: count i by sym from trade where date within 2014.08.07 2014.08.11
* IBM 股票在特定时间范围内的最高价格是多少?何时首次发生?
select time,ask from quote where date within 2014.08.07 2014.08.11, sym =`IBM, ask = exec first ask from select max ask from quote where sym =`IBM
选择每小时存储桶中每个符号的最后价格
select last price by hour:time.hh, sym from trade
聚合查询
* 计算所有交易品种的 vwap(成交量加权平均价格)
select vwap:size wavg price by sym from trade
* 统计某个月份的记录数(以百万为单位)
(select trade:1e-6*count i by date.dd from trade where date.month=2014.08m) + select quote:1e-6*count i by date.dd from quote where date.month=2014.08m
* HLOC – CSCO 在某个月份的每日最高价、最低价、开盘价和收盘价
select high:max price,low:min price,open:first price,close:last price by date.dd from trade where date.month=2014.08m,sym =`CSCO
* CSCO 某月每日交易量
select vwap:size wavg price by date.dd from trade where date.month = 2014.08m ,sym = `CSCO
* 计算 AIG 价格的每小时均值、方差和标准差
select mean:avg price, variance:var price, stdDev:dev price by date, hour:time.hh from trade where sym = `AIG
选择每小时的价格范围
select range:max[price] – min price by date,sym,hour:time.hh from trade
* CSCO 某月每日点差(平均买卖价)
select spread:avg bid-ask by date.dd from quote where date.month = 2014.08m, sym = `CSCO
* 特定月份所有符号的每日交易价值
select dtv:sum size by date,sym from trade where date.month = 2014.08m
为 CSCO 提取 5 分钟 vwap
select size wavg price by 5 xbar time.minute from trade where sym = `CSCO
* 为 CSCO 提取 10 分钟柱
select high:max price,low:min price,close:last price by date, 10 xbar time.minute from trade where sym = `CSCO
* 查找某一天 CSCO 价格比最后价格超过 100 个基点 (100e-4) 的次数
select time from trade where date = 2014.08.11,sym = `CSCO,price > 1.01*last price
* 数据库中最后日期的 MSFT 全日价格和交易量(以 1 分钟为间隔)
select last price,last size by time.minute from trade where date = last date, sym = `MSFT