@art_karetnikov
Лучший мой проект: Мобильный банк Сбербанка РФ.

На три четверти знаю, что нужно сделать — LAG или подзапрос?

Есть вот такой запрос:
SELECT
s.m_date,
s.id_tool
FROM tbl_snap s
WHERE s.m_date NOT IN ( SELECT s.m_date FROM tbl_snap s
JOIN tbl_tool t ON s.id_tool = t.id_tool AND t.id_tool_type = 1 AND is_trade = 1
)
ORDER BY s.m_date DESC;

Есть инструменты двух типов. По одним из них значение m_close в таблице tbl_snap есть каждый день, по другим, их тип id_tool_type = 1 - только по рабочим дням. Соответственно, я в этом запросе отбираю только те даты, которые не рабочие.

Хочу по этим нерабочим дням чтобы отображались те id_tool, по которым данных нет и подставлялось их значение от прошлой даты, когда данные были.
Каждый день были бы данные по всем инструментам, независимо от того, есть ли они реально в таблице tbl_snap на этот день. Образец:

date | tool | type | is_trade m_close
-----|------|------|----------
2023-07-04 5 2 1 15.00
2023-07-04 6 2 1 13.10
2023-07-03 1 1 1 1.02
2023-07-03 2 1 1 2.01
2023-07-03 5 2 1 14.00
2023-07-03 6 2 1 11.10

по id_tool in (5, 6) данные за 4 июля есть. По id_tool in (1, 2) - нет. Тогда должно получиться

date | tool | type | is_trade m_close
-----|------|------|----------
2023-07-04 5 2 1 15.00
2023-07-04 6 2 1 13.10
2023-07-04 1 1 1 1.02
2023-07-04 2 1 1 2.01
2023-07-03 1 1 1 1.02
2023-07-03 2 1 1 2.01
2023-07-03 5 2 1 14.00
2023-07-03 6 2 1 11.10

Надеюсь, понятно объяснил. И чувствую, что решение на поверхности, но глаз замылился. :(
  • Вопрос задан
  • 36 просмотров
Решения вопроса 1
@art_karetnikov Автор вопроса
Лучший мой проект: Мобильный банк Сбербанка РФ.
В общем, отвечу другим юношам, обдумывающим житьё.

select m_date, id_tool, m_close
-- вот так получаю предыдущее значение, там, где текущее значение равно NULL
, COALESCE(m_close, LAG(m_close) OVER (PARTITION BY id_tool ORDER BY m_date)) AS m_close
from
(
SELECT distinct s.m_date, t.id_tool, null as m_close -- вот так добавляю несуществущие данные в запрос
FROM tbl_snap s
CROSS join tbl_tool t on t.is_trade = 1 and t.id_tool_type = 1
WHERE m_date not in (
SELECT m_date
FROM tbl_tool t
join tbl_snap s on s.id_tool = t.id_tool
WHERE t.id_tool_type = 1
)
UNION all -- все остальные данные
select m_date, id_tool, m_close
from tbl_snap s
)
ORDER by m_date desc, id_tool

У этого запроса есть один недостаток. Если два дня подряд не было торгов, то LAG не вернет данные, будет NULL.

Избавиться от этой проблемы можно подзапросом, вместо LAG - (
SELECT m_close
FROM tbl_snap s2
WHERE s2.id_tool = s.id_tool
AND s2.m_date < s.m_date
ORDER BY s2.m_date DESC
LIMIT 1
) m_close - однако это существенно увеличит время выполнения
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы