我在 SQL 表中有一些数据如下所示:
TIMESTAMP SYMBOL PRICE VOLUME RATIO ITERATION
2017-10-04 ABC 1.23 12 0.78 1
2017-10-05 ABC 1.33 10 0.49 2
2017-10-06 ABC 1.73 10 0.69 3
2017-10-04 XYZ 1.73 10 0.69 1
...
我正在尝试编写一个查询,该查询将返回与timestamp
和symbol
匹配的所有记录(使用简单的WHERE
子句),但也包括之前price
当前记录中的前一个iteration
。
例如,如果我想返回与symbol=ABC
和timestamp=2017-10-06
匹配的所有记录,则查询将返回:
TIMESTAMP SYMBOL PRICE VOLUME RATIO ITERATION PREV_PRICE
2017-10-06 ABC 1.73 10 0.69 3 1.33
其中PREV_PRICE
是匹配price
和symbol=ABC
的记录的iteration=2
(当前记录迭代值减去1)。
我可以通过实现多个查询和循环来通过代码执行此操作,但我希望在 SQL 本身中找到一种方法。
可以从与查询记录匹配相同price
的上一次迭代记录中检索symbol
数据吗?
答案 0 :(得分:2)
大多数数据库都支持ANSI标准lag()
。但是你必须要小心,因为你需要在过滤之前进行lag()
:
select t.*
from (select t.*,
lag(t.price) over (partition by symbol order by timestamp) as prev_price
from t
where t.symbol = 'ABC'
) t
where t.timestamp = '2017-10-06';
在子查询中对symbol
进行过滤是安全的,因为它用于分区。但是,timestamp
上的过滤器需要位于外部查询中,以便lag()
完成其工作。
答案 1 :(得分:1)
您需要做的就是使用您在问题中列出的标准将表格加入到自身中。这应该有效:
SELECT t1.*, t2.PRICE as PREV_PRICE
FROM my_table t1
LEFT JOIN my_table t2 ON (t2.SYMBOL = t1.SYMBOL AND t2.ITERATION = (t1.ITERATION - 1))
WHERE t1.TIMESTAMP = '2017-10-06'
AND t1.SYMBOL = 'ABC'
您也可以对子查询执行相同的操作:
SELECT t1.*,
(SELECT PRICE FROM my_table t2 WHERE t2.ITERATION = (t1.ITERATION - 1)) AS PREV_PRICE
FROM my_table t1
WHERE t1.TIMESTAMP = '2017-10-06'
AND t1.SYMBOL = 'ABC'
答案 2 :(得分:0)
包含子查询以获取先前的价格。获取小于给定时间戳的时间戳的最大价格。这将给出与之前时间戳相对应的价格。
SELECT y1.*,
(SELECT max (price)
FROM yourtable y
WHERE symbol = 'ABC'
AND timestamp < '2017-10-06') prev_price
FROM yourtable y1
WHERE symbol = 'ABC'
AND timestamp = '2017-10-06'