Выберите дату и значение между двумя датами с совокупной суммой - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь суммировать каждый день между двумя датами без потери последнего значения.

Немного контекста:

2020-02-03 have 27 registers
2020-02-04 have 32 registers
2020-02-05 have 28 registers and so on...

Итак, я сделал этот запрос:

set @CumulativeSum := 0;
select date(t1.created_at), (@CumulativeSum := @CumulativeSum + 
     (select count(*)
     from services_aux t2
     where date(t2.created_at) = date(t1.created_at))) as value
from services_aux t1
where (t1.created_at BETWEEN '2020-02-01' AND '2020-02-07')
group by date(t1.created_at)

Первый результат нормальный, но неверная сумма. Получил:

date       | value
------------------
2020-02-03 | 27
2020-02-04 | 761
2020-02-05 | 1781

Но жду:

date       | value
------------------
2020-02-03 | 27
2020-02-04 | 59
2020-02-05 | 87

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Если вы используете MySQL 8.0, просто используйте оконные функции, как продемонстрировал Тим Бигелейзен.

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

set @cnt := 0;
select created_day, @cnt := @cnt + cnt as value
from (
    select date(t1.created_at) created_day, count(*) cnt
    from services_aux t1
    where t1.created_at between '2020-02-01' and '2020-02-07'
    group by date(t1.created_at)
    order by created_day
) t
0 голосов
/ 27 мая 2020

Запросы с пользовательскими переменными в MySQL могут быть сложными. Если вы используете MySQL 8+, то мы можем просто использовать COUNT как аналитическую c функцию:

SELECT
    DATE(created_at) AS created_at,
    COUNT(*) OVER (ORDER BY DATE(created_at)) cnt
FROM services_aux
WHERE
    created_at BETWEEN '2020-02-01' AND '2020-02-07'
GROUP BY
    DATE(created_at);

Если вы используете более раннюю версию, я предлагаю просто использовать коррелированную подзапрос, чтобы найти текущее количество:

SELECT
    DATE(sa1.created_at) AS created_at,
    (SELECT COUNT(*) FROM services_aux sa2
     WHERE DATE(sa2.created_at) <= DATE(sa1.created_at)) cnt
FROM services_aux sa1
WHERE
    sa1.created_at BETWEEN '2020-02-01' AND '2020-02-07'
GROUP BY
    DATE(sa1.created_at);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...