如何查询SQL记录并将列数据包含在另一行中?

时间:2017-10-04 18:23:21

标签: sql azure-sql-database

我在 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
...

我正在尝试编写一个查询,该查询将返回与timestampsymbol匹配的所有记录(使用简单的WHERE子句),但包括之前price当前记录中的前一个iteration

例如,如果我想返回与symbol=ABCtimestamp=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是匹配pricesymbol=ABC的记录的iteration=2(当前记录迭代值减去1)。

我可以通过实现多个查询和循环来通过代码执行此操作,但我希望在 SQL 本身中找到一种方法。

可以从与查询记录匹配相同price的上一次迭代记录中检索symbol数据吗?

3 个答案:

答案 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'