@Danaika

Статистика. Как «вытащить» в одну строку данные за 2 даты?

Доброго времени суток!

Предположим у меня есть таблица stat со следующими столбцами: id, date, param, value
(таблица именно в такой структуре нормализовать/менять ее нельзя, она ко мне в таком виде приходит)
один и тот же параметр может повторятся в разных датах.
В конце я хочу получить примерно следующее: значение одного параметра на сегодня и в этой же строке значение этого же параметра но на вчера.

id | param| date| value| previous date| previous value|
2 | param1|2021-11-30| 45| 2021-11-29| 40|

Возможно ли так вывести?
  • Вопрос задан
  • 81 просмотр
Решения вопроса 1
ThunderCat
@ThunderCat Куратор тега MySQL
{PHP, MySql, HTML, JS, CSS} developer
В чистом виде скорее всего это будет какой-то треш, типа вычисляемых подзапросом полей, по этому:
1) Не понятно почему бы не получить это строками и обработать уже программно
2) Можно сгруппировать и конкатинировать, но так как все равно это не будет отдельным полем, тоже понадобятся некоторые программные манипуляции.

И какова цель всего этого?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@kamenyuga
Другой ответ, конечно, утверждает про треш. Но по мне задача звучит, как самый обычный и довольно простой запрос в базу данных, который даже без гугла пишется за пару минут. Если, конечно, работал с sql хотя бы на уровне джуна.

К сожалению, я работаю с ораклом, поэтому напишу на оракловом диалекте. sysdate - это текущие дата и время. trunc - округляет дату и время до даты. trunc(sysdate) - 1 - это ноль часов вчерашнего дня.
select
    parameter_column,
    trunc(sysdate) as date_today,
    max(case when date_column < trunc(sysdate) then value_column end) as value_today,
    trunc(sysdate) as date_yesterday,
    max(case when date_column >= trunc(sysdate) then value_column end) as value_yesterday
from target_table
where date_column >= trunc(sysdate) - 1
group by parameter_column

Запрос вычисляет максимальное значение параметров за сегодня и за вчера, если их было несколько. Если только один, то на выходе это единственное значение. Если не было, то NULL. Тут уж нужны детали о том, как именно устроены данные.

Если в таблице существует ровно одно значение параметра в один день, то запрос намного упрощается - нужна одна-единственная оконная функция, даже case-when руками писать не надо. lag к текущей строке подтягивает предыдущую строку, так что можно объединять значения из двух строк в одной.
select
    parameter_column,
    date_column as date_today,
    value_column as value_today,
    lag(date_column) over(partition by parameter_column order by date_column) as date_yeaterday,
    lag(value_column) over(partition by parameter_column order by date_column) as value_yeaterday
from target_table
where date_column >= trunc(sysdate)

Если все же значений бывает много в одну дату, то надо будет фильтр настроить - отбирать строки в которых первая дата - сегодняшняя, а вторая - вчерашняя.

Вот уже два варианта решить задачу в первом приближении. Повторюсь, что это оракловый диалект sql.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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