如何正确使用SQL LAG()

时间:2019-02-09 03:34:07

标签: sql postgresql lag

我下面的SQL行存在语法错误。我正在尝试在SQL查询中引用前一天的收盘价,如何解决我的查询不出错的问题?

谢谢!

SELECT *
FROM "daily_data"
WHERE date >'2018-01-01' and (open-LAG(close))/LAG(close)>=1.4 and volume > 1000000 and open > 1 

错误:

  

查询执行失败   原因:SQL错误[42809]:错误:窗口函数滞后需要OVER   子句位置:63

2 个答案:

答案 0 :(得分:0)

您需要使用子查询。您不能在where子句中使用窗口函数。您还需要一个ORDER BY并可能需要一个PARTITION BY子句:

SELECT *
FROM (SELECT dd.*,
             LAG(close) OVER (ORDER BY date) as prev_close
      FROM "daily_data" dd
     ) dd
WHERE date > '2018-01-01' AND
      (open - prev_close) / prev_close >= 1.4 AND
      volume > 1000000 AND
      open > 1;

答案 1 :(得分:0)

lag(close)表示“距先前记录的收盘价”。因此,该短语本身缺少一些基本知识,特别是由于RDBMS中从不存在任何隐含顺序,因此您如何定义“先前记录”。

rankrow_number之类的功能一样,要正确形成leadlag命令,您需要通过定义以下内容来建立先前(或下一条)记录:输出顺序。换句话说,“如果要按x对输出进行排序,则先前的记录将关闭”:

lag (close) over (order by x)

以降序排列:

lag (close) over (order by x desc)

您可以选择使用partition by按字段对数据进行分块,这在您的问题中可能有用也可能没有用。例如,“对于每个项目,如果您要按x排序输出,则先前的记录将关闭:”

lag (close) over (partition by item order by x)

这里的问题是先验记录(滞后)...如何?通过哪些字段,以什么顺序?

作为最后的想法,不能在PostgreSQL的where子句中使用分析/窗口函数。为此,请将它们包装在子查询中:

with daily as (
  SELECT
    d.*,
    LAG (d.close) over (order by d.<something>) as prior_close
  FROM "daily_data" d
  WHERE
    d.date >'2018-01-01' and
    d.volume > 1000000 and
    d.open > 1
)
select *
from daily
where
  (open - prior_close) / prior_close >= 1.4