Совокупный итог MySQL, сгруппированный по дням при максимальном общем количестве

#mysql #sql #datetime #sum #window-functions

#mysql #sql #дата и время #сумма #окно-функции

Вопрос:

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

в настоящее время у меня есть:

 SELECT
  DATE_FORMAT(created_at, '%d/%m') AS day1,
  SUM(principal) over (order by created_at) AS tot
FROM loan;
  

ВЫВОД:

 [
    {
        "day1" : "21/08",
        "tot" : 200
    },
    {
        "day1" : "21/08",
        "tot" : 1200
    },
    {
        "day1" : "21/08",
        "tot" : 2200
    },
    {
        "day1" : "21/08",
        "tot" : 2500
    },
    {
        "day1" : "25/08",
        "tot" : 4500
    },
    {
        "day1" : "25/08",
        "tot" : 6500
    },
    {
        "day1" : "27/08",
        "tot" : 7000
    },
    {
        "day1" : "27/08",
        "tot" : 7600
    }
]
  

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

Когда я группируюсь примерно так:

 SELECT
  DATE_FORMAT(created_at, '%d/%m') AS day1,
  SUM(principal) over (order by created_at) AS tot
FROM loan
GROUP BY day1;
  

Я получаю:

 [
    {
        "day1" : "21/08",
        "tot" : 1000
    },
    {
        "day1" : "25/08",
        "tot" : 3000
    },
    {
        "day1" : "27/08",
        "tot" : 3500
    },
    {
        "day1" : "30/08",
        "tot" : 4200
    }
]
  

Что, очевидно, неверно. Я не уверен, почему это дает такой результат. Но как я мог заставить его быть правильным?

Комментарии:

1. Пожалуйста, покажите нам результаты, которые вы хотите.

Ответ №1:

Вам нужно вложить суммы:

 SELECT DATE_FORMAT(created_at, '%d/%m') AS day1,
       SUM(SUM(principal)) OVER (ORDER BY MIN(created_at)) AS tot
FROM loan
GROUP BY day1;
  

Я удивлен, что ваша версия вообще работает. В большинстве баз данных это приведет к сбою, потому что ни principal один, ни created_at один не являются ключами агрегации.

Ответ №2:

Предположительно, вы хотите:

 select
    date_format(created_at, '%d/%m') as day1,
    max(sum(principal) over (order by created_at)) as tot
from loan
group by day1
  

На самом деле, вы также могли бы выразить это с distinct помощью, и немного другого order by предложения:

 select distinct
    date_format(created_at, '%d/%m') as day1,
    sum(principal) over (order by date(created_at)) as tot
from loan
  

Я не большой поклонник того, как вы представляете даты; если ваши данные распространяются более чем на один год, результат станет неоднозначным (во втором варианте) или даже неправильным (в первом запросе). Я бы рекомендовал добавить год к представлению даты или просто date(created_at) , что в основном сокращает временную часть.