Задать вопрос
@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

Надеюсь, понятно объяснил. И чувствую, что решение на поверхности, но глаз замылился. :(
  • Вопрос задан
  • 39 просмотров
Подписаться 1 Простой 2 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Инженер по тестированию
    5 месяцев
    Далее
  • Нетология
    Инженер по тестированию
    8 месяцев
    Далее
  • Thinknetica
    Профессиональная разработка на Ruby on Rails
    9 месяцев
    Далее
Решения вопроса 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 - однако это существенно увеличит время выполнения
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽