За последние 24 часа нас посетили 22529 программистов и 1143 робота. Сейчас ищут 862 программиста ...

Сгруппировать сумму за каждый месяц для графика

Тема в разделе "PHP и базы данных", создана пользователем Mirnyi, 21 июл 2019.

  1. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Всем привет. Ребят подскажите пожалуйста как можно сгруппировать сумму за каждый месяц
    ['месяц.год', общая сумма за этот месяц.год]
    Необходимо прийти к виду:
    ['04.2019', 65], ['05.2019', 15], ['06.2019', 57], ['07.2019', 200]
    у меня же получается следующее:
    ['04.2019', 15], ['04.2019', 50], ['05.2019', 7], ['05.2019', 8], ['06.2019', 12], ['06.2019', 45], ['07.2019', 37], ['07.2019', 92], ['07.2019', 71]
    То есть у меня просто вывод ['дата', сумма], а нужно ['месяц.год', общая сумма за этот месяц.год]
    Дата в unix
    мой код
    Код (Text):
    1.  
    2. $sql=$mgrdb->query("SELECT * FROM `services_bill` WHERE `status`='3' and `paytypekassa`='1'");
    3.         $row2=$sql->fetchAll(PDO::FETCH_ASSOC);
    4.         $arr = array();
    5.         foreach($row2 as $row){
    6.         $datatime = date("m.Y", $row['date']);
    7.         $arr[] = "['".$datatime."', {$row['amount']}]";
    8.         }
    9.     $stats = implode(", ", $arr);
    10.     $DATA['stats'] = $stats;
     
  2. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Mirnyi,
     
  3. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Sail, а почему бы не заставить СУРБД поработать по её непосредственному назначению?
     
  4. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Возможно, конечно, что нужны только накопительные суммы...
     
  5. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Мне нужна не общая сумма, а за каждый месяц, ['период', сумма]. Общую сумму получаю в запросе:
    "SELECT SUM(`amount`) AS summ FROM `services_bill` WHERE `status`='3' and `paytypekassa`='1'"
    а как получить сумму каждого месяца не знаю
    --- Добавлено ---
    Не получается у меня, из за нехватки знаний)
    К примеру сумму дохода за сегодня я получаю так:
    Код (Text):
    1. $day1 = strtotime("today 00:00");
    2. $sqlday1 = $mgrdb->query("SELECT SUM(`amount`) AS summ, `date` FROM `services_bill` WHERE `date`>= '".$day1."' and `status`='3' and `paytypekassa`='1'");
    за вчерашний день так:
    Код (Text):
    1. $day2 = strtotime("today -1 day");
    2. $sqlday2 = $mgrdb->query("SELECT SUM(`amount`) AS summ, `date` FROM `services_bill` WHERE `date`> '".$day2."' and `date`<'".$day1."' and `status`='3' and `paytypekassa`='1'");
    Даход за всё время:
    Код (Text):
    1. $sql_amount = $db->query("SELECT SUM(`amount`) AS summ FROM `services_bill` WHERE `status`='3' and `paytypekassa`='1'");
    А для графика мне необходимо получить данные вида:
    ['04.2019', 65], ['05.2019', 15], ['06.2019', 57], ['07.2019', 200]
    не знаю как это сделать
     
  6. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
  7. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Что-то мешает использовать для накомления не одну переменную, а массив вида ['месяц.год' => сумма]?
     
  8. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Пример можете подсказать? Я пробовал так:
    Код (Text):
    1. $sqlday1 = $mgrdb->query("SELECT SUM(`amount`) AS summ, `date` FROM `services_bill` WHERE `date`>= MONTH(`date`) and `status`='3' and `paytypekassa`='1' GROUP BY MONTH(date)");
    Не получается
    --- Добавлено ---
    нехватка знаний)
     
  9. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Первое простое условие какое-то странное. Чтобы не мешались месяцы разных лет, достаточно выбирать записи за последний год или просто не хранить старые записи в осн. таблице. Также можно выбирать записи за конкретный год.
     
  10. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Я пытаюсь построить график как на скриншоте
    [​IMG]
     
  11. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Тогда вам нужно группировать не по номеру месяца, а по паре год-месяц.
     
    artoodetoo нравится это.
  12. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Именно это я и пытаюсь сделать, просто не грамотно оформил тему(
     
  13. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Пробую запрос:
    SELECT format(date,'MM.yyyy') AS Mjesec, SUM(amount) AS summ
    FROM services_bill
    WHERE `status`='3' and `paytypekassa`='1'
    GROUP BY format(date,'MM.yyyy')
    какая то белиберда получается)
    весь код:
    Код (Text):
    1. $sql=$mgrdb->query("
    2. SELECT format(date,'MM.yyyy') AS Mjesec, SUM(amount) AS summ
    3. FROM services_bill
    4. WHERE `status`='3' and `paytypekassa`='1'
    5. GROUP BY format(date,'MM.yyyy')
    6. ");
    7. $row2=$sql->fetchAll(PDO::FETCH_ASSOC);
    8. $arr = array();
    9. foreach($row2 as $row){
    10.     $arr[] = "['{$row['Mjesec']}', {$row['summ']}]";
    11. }
    12. $stats = implode(", ", $arr);
    13. $DATA['stats'] = $stats;
    результат на скриншоте
    [​IMG]
    Может кто то подскажет как сформировать правильно запрос?
     
  14. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Неужели никто не сталкивался с подобной задачей?
    Может кто то за $ поможет?
     
  15. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Mirnyi, сталкивались и не раз. Просто нет времени сесть за комп.
     
  16. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Как будет время напишите пожалуйста.
     
  17. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Mirnyi, какой тип имеют данные в поле `date` таблицы `services_bill`?
    --- Добавлено ---
    Посмотрите на 6-ю строку приведённого в первом сообщении кода. Выполняется преобразование функцией date().
    --- Добавлено ---
    В MySQL тоже есть функции для обработки даты.
     
    Mirnyi нравится это.
  18. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Ф-цию выбрали явно неподходящую. Попробуйте в лоб: сделайте динамическое поле, исходя из выражения год*100+месяц, по которому и группируйте, и сортируйте. Ссылку для оплаты моего пивасика скину в личку :)
    --- Добавлено ---
    P.S. Преобразовывать полученные числа в формат 'MM.YYYY' можно на пыхе, объединяя с суммами. Можно все это и на мускуле сделать, тогда вам отдельное поле с суммами вообще не нужно, если вы не планируете по нему сортировать.

    Поле с числами год-месяц можно получить и при помощи ф-ции форматирования даты. Только не забудьте ее обрамить ф-цией преобразования строки в число.
     
    Mirnyi нравится это.
  19. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    А должно получаться именно то, о чём ты просил ))) SQL запрос правдоподобный. Только от названия Mjesec хочется блевать, а так - вполне ничего себе. Имей в виде только, что группировка создаёт неявную сортировку и в твоём случае сначала будет отсортировано по месяцу, затем по году. А логично было бы выставить год вперёд как 'yyyy.mm'. Сами суммы будут правильные в любом случае.
    Edited: DATE_FORMAT()

    Подсказка: во фразе group by ты можешь указать просто номер колонки из фразы select. В твоём случае это
    GROUP BY 1
     
    #19 artoodetoo, 23 июл 2019
    Последнее редактирование: 23 июл 2019
    Mirnyi нравится это.
  20. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Mirnyi, ах, да, там-же написано, что "Дата в unix" :)
    Вот выражение: date_format(from_unixtime(`date`),'%Y.%m')
     
    Mirnyi и artoodetoo нравится это.
  21. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    @Sail, from_unixtime сама поддерживает заказное форматирование ;)
    --- Добавлено ---
    По-моему все же лучше писать интуитивно понятно:
    Код (Text):
    1. ORDER BY `Mjesec`
    Хотя ты прав в том, что потом ХП, что такое Mjesec :)
    --- Добавлено ---
    @Mirnyi, пиши все имена полей и т.п. в «косых кавычках» (см. мой пример кода выше), чтобы они не конфликтовали с именами ф-ций и т.п.
     
    Mirnyi нравится это.
  22. Mirnyi

    Mirnyi Активный пользователь

    С нами с:
    21 июл 2019
    Сообщения:
    9
    Симпатии:
    2
    Спасибо большое ребят, очень помогли! Всё работает как надо.
    Sail, miketomlin и artoodetoo напишите в лс Qiwi, кину по паре соток на пивко)

    Mjesec - это название я взял из примера который нагуглил)

    Готовый код (в график выводиться год.месяц и сумма)
    Код (Text):
    1. $sql=$mgrdb->query("
    2. SELECT date_format(from_unixtime(`date`),'%Y.%m') AS `date`, SUM(amount) AS `sum`
    3. FROM `services_bill`
    4. WHERE `status`='3' and `paytypekassa`='1'
    5. GROUP BY 1
    6. ");
    7. $row2=$sql->fetchAll(PDO::FETCH_ASSOC);
    8. $arr = array();
    9. foreach($row2 as $row){
    10.     $arr[] = "['{$row['date']}', {$row['sum']}]";
    11. }
    12. $stats = implode(", ", $arr);
    13. $DATA['stats'] = $stats;
    [​IMG]

    Другой вариант, тоже работает.
    Готовый код (в график выводиться месяц.год и сумма)
    Код (Text):
    1. $sql=$mgrdb->query("
    2. SELECT date_format(from_unixtime(`date`),'%m.%Y') AS `date`, SUM(amount) AS `sum`
    3. FROM `services_bill`
    4. WHERE `status`='3' and `paytypekassa`='1'
    5. GROUP BY date_format(from_unixtime(`date`),'%Y.%m')
    6. ");
    7. $row2=$sql->fetchAll(PDO::FETCH_ASSOC);
    8. $arr = array();
    9. foreach($row2 as $row){
    10.     $arr[] = "['{$row['date']}', {$row['sum']}]";
    11. }
    12. $stats = implode(", ", $arr);
    13. $DATA['stats'] = $stats;
    [​IMG]
     
    artoodetoo и Valick нравится это.
  23. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Попробуйте учесть мое замечание по поводу from_unixtime:
    Код (Text):
    1. SELECT from_unixtime(`date`,'%m.%Y') AS `date`
    И группировать/сортировать все же лучше по числам:
    Код (Text):
    1. SELECT from_unixtime(`date`,'%Y%m')+0 `month`, SUM(`amount`) `sum` WHERE ... GROUP BY `month` ORDER BY `month`
    Можно и разделить значения для представления и значения для группировки/сортировки прямо в запросе.
    --- Добавлено ---
    Хотя значения вроде 201907 хорошо подходят и для ф-ции представления на пыхе.
     
    Mirnyi нравится это.