Как правильно использовать sql 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 

Ошибка:

Query execution failed Reason: SQL Error [42809]: ERROR: window function lag requires an OVER clause Position: 63

предоставьте образцы данных и ожидаемый результат в формате таблицы

Fahmi 09.02.2019 04:34
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
1
1 704
2

Ответы 2

Вам нужно использовать подзапрос. Вы не можете использовать оконные функции в предложении 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;

Я получаю следующую ошибку, когда пытаюсь это сделать: Ошибка SQL [42601]: ОШИБКА: подзапрос в FROM должен иметь псевдоним Подсказка: например, FROM (SELECT ...) [AS] foo. Позиция: 16 ОШИБКА: подзапрос в FROM должен иметь псевдоним Подсказка: Например, FROM (SELECT ...) [AS] foo. Позиция: 16 ОШИБКА: подзапрос в FROM должен иметь псевдоним Подсказка: Например, FROM (SELECT ...) [AS] foo. Позиция: 16

user1144251 09.02.2019 04:43

lag(close) означает «значение закрытия из предыдущей записи». Таким образом, в самой фразе отсутствует что-то фундаментальное, в частности, как вы определяете «предыдущую запись», поскольку в РСУБД никогда не существует подразумеваемого порядка.

Как и в случае с такими функциями, как rank и row_number, для правильного формирования команд lead и lag вам необходимо установить предыдущую (или следующую) запись, определив порядок вывода. Другими словами, «если бы вы отсортировали вывод по 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)

На вопрос здесь предварительная запись (лаг)... как? По каким полям, в каком порядке?

И наконец, аналитические/оконные функции нельзя использовать в предложении where в PostgreSQL. Для этого оберните их в подзапрос:

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

Другие вопросы по теме