Это? Спойлер: code Код (Text): SELECT `role`, COUNT(`id`) AS `count`, DATE(`date_create`) as `date_create` FROM `db_profile` WHERE DATE(`date_create`) IN (SELECT DISTINCT DATE(`date_create`) FROM `db_profile` WHERE `date_create` >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)) GROUP BY `role`, DATE(`date_create`) Дело в том, что здесь у меня (и скрипт и phpmyadmin) выводит 1 строка = 1 дате. Всего 7 строк. На fiddle да, три строки на дату. UPDATE: Ошибся. Разбираюсь.
Это, да. Не знаю почему так. Судя по структуре исходной таблицы у вас версия mysql отличная от моей. MariaDB наверное. Там есть свои особенности.
Не извращение ли это? Код (Text): $arrAll = []; foreach ($res as $value) { //var_dump($value); foreach ($value as $k => $v) { if ($k == "date_create") { $arrAll[$v] = [ 'role' => [ "admin" => ($value["role"] == "admin") ? $value["count"] : '', "mod" => ($value["role"] == "mod") ? $value["count"] : '', ], 'count' => $value["count"], ]; } } } В общем хрень! Есть ещё варианты? Что бы сразу с базы корректно формировать.
PHP: <?php $db_result = array( array('role' => 'Admin', 'count' => '7', 'date_create' => '2021-01-29'), array('role' => 'Moder', 'count' => '2', 'date_create' => '2021-01-29'), array('role' => 'Vasya', 'count' => '1', 'date_create' => '2021-01-29'), array('role' => 'Admin', 'count' => '7', 'date_create' => '2021-01-30'), array('role' => 'Moder', 'count' => '1', 'date_create' => '2021-01-30'), array('role' => 'Vasya', 'count' => '2', 'date_create' => '2021-01-30') ); $empty_element = array('Admin' => 0, 'Moder' => 0, 'Vasya' => 0); $new_array = array(); foreach($db_result as $row) { if(!isset($new_array[$row['date_create']])) $new_array[$row['date_create']] = $empty_element; $new_array[$row['date_create']][$row['role']] = $row['count']; } echo '<pre>'; print_r($new_array); foreach($new_array as $key => $value) { echo $key.': '.join(',',$value).'<br>'; } ?>
Закрывая, так сказать, тему, хочу заметить, что, собственно, в отдельных колонках всё это дело вывести таки можно. Но, запрос будет выглядеть довольно монструозно. Сейчас выдалась свободная минутка, вот, наваял: Код (Text): SELECT * FROM (SELECT COUNT(*) AS `count_admin`, DATE(`date_create`) as `date` FROM `db_profile` WHERE DATE(`date_create`) IN (SELECT DISTINCT DATE(`date_create`) FROM `db_profile` WHERE `date_create` >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)) AND `role` = 'Admin' GROUP BY `role`, `date`) AS `t1`, (SELECT COUNT(*) AS `count_moder`, DATE(`date_create`) as `date` FROM `db_profile` WHERE DATE(`date_create`) IN (SELECT DISTINCT DATE(`date_create`) FROM `db_profile` WHERE `date_create` >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)) AND `role` = 'Moder' GROUP BY `role`, `date`) AS `t2`, (SELECT COUNT(*) AS `count_vasya`, DATE(`date_create`) as `date` FROM `db_profile` WHERE DATE(`date_create`) IN (SELECT DISTINCT DATE(`date_create`) FROM `db_profile` WHERE `date_create` >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)) AND `role` = 'Vasya' GROUP BY `role`, `date`) AS `t3` WHERE `t1`.`date` = `t2`.`date` AND `t2`.`date` = `t3`.`date` Думаю, можно согласиться, что вариант "одна дата - три строки" куда симпатичней.
Думаю решающий фактор скорость. Нужно просто сравнить. В первом варианте приходится в цикле всё прогонять. В целом работает, ещё раз спасибо!
@AlexProg, агрегатные функции - не только count. Если уж заранее известны роли - можно и просуммировать количества Код (SQL): SELECT DATE(date_create), SUM(IF(ROLE = 'Admin', 1, 0)) AS cnt_Admin, SUM(IF(ROLE = 'Vasya', 1, 0)) AS cnt_Vasya, SUM(IF(ROLE = 'Moder', 1, 0)) AS cnt_Moder FROM db_profile WHERE DATE(`date_create`) >= DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY) GROUP BY DATE(date_create) PS: Функция date() использована потому, что в наборе данных для теста поле date_create содержит не только дату, но и время.