Dynamic Pivot в MySQL - Как зацикливаться на полях из select внутри хранимой процедуры mySQL? - PullRequest
0 голосов
/ 21 октября 2019

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

Мой план - вызвать хранимую процедуру mySQL. Эта процедура должна вернуть что-то вроде этого:

+---------------+---------------+---------------+---------------+---------------+
| Date          | 100           | 101           | 102           | 103           |
+---------------+---------------+---------------+---------------+---------------+
| 2019-10-21    | 1             | 2             | 3             | 4             |
| 2019-10-20    | 0             | 2             | 3             | 4             |
| 2019-10-19    | 0             | 2             | 3             | 4             |
| 2019-10-18    | 1             | 2             | 3             | 4             |
| 2019-...      | ..            | ..            | ..            | ..            |
+---------------+---------------+---------------+---------------+---------------+

"Основные данные" были сохранены в таблице "loggings", которая имеет столбцы id, code, creation_at. Вторая таблица «коды» содержит список всех доступных кодов с идентификаторами столбцов (<- код в журналах) и описанием. </p>

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

BEGIN
set @dateStart := (SELECT MIN(created_at) FROM loggings);
set @dateEnd := (SELECT MAX(created_at) FROM loggings);
set @d := 0;
SELECT DATE(ADDDATE(@dateStart, INTERVAL @d:=@d+1 DAY)) AS date,
IFNULL((
    SELECT COUNT(*) FROM loggings AS m2
    WHERE DATE(m2.created_at) = DATE(ADDDATE(@dateStart, INTERVAL @d DAY))
),0) AS total
FROM loggings AS m1
HAVING @d < DATEDIFF(@dateEnd, @dateStart);
END

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

+---------------+---------------+
| date          | total         |
+---------------+---------------+
| 2019-10-21    | 1             |
| 2019-10-20    | 2             |
| 2019-10-19    | 3             |
| 2019-10-18    | 4             |
| 2019-...      | ..            |
+---------------+---------------+

Теперь, следующая часть, которую я не делаюВ настоящее время не совсем понятно, как я могу решить эту проблему: как я могу зациклить доступные идентификаторы «кодов» в набор столбцов для результата? Каким-то образом я должен построить цикл внутри / снаружи выбранных возвращающих динамических полей, но как?

Редактировать: Пример данных может быть:

+----------+----------+----------+----------------------+
| id       | email    | code     | created_at           |
+----------+----------+----------+----------------------+
| 1        | a@y.de   | 100      | 2019-10-21 10:00:01  |
| 2        | b@y.de   | 100      | 2019-10-21 10:00:02  |
| 3        | c@y.de   | 101      | 2019-10-21 10:01:03  |
| 4        | d@y.de   | 102      | 2019-10-21 11:01:03  |
| 5        | a@y.de   | 100      | 2019-10-21 12:01:03  |
| 6        | b@y.de   | 103      | 2019-10-21 15:01:03  |
| 7        | e@y.de   | 106      | 2019-10-21 15:01:04  |
| 8        | f@y.de   | 108      | 2019-10-21 16:01:03  |
| 9        | g@y.de   | 109      | 2019-10-21 17:01:03  |
+----------+----------+----------+----------------------+

Таблица регистрирует различные события по их коду сметка времени создания и адрес электронной почты в качестве ключа для идентификации пользователя, запускает «событие».

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Конечный результат, который вы пытаетесь достичь, называется Dynamic Pivot . Вы можете попробовать запрос ниже, чтобы достичь желаемого результата -

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'count(case when code = ',
      code,
      ' then created_at else null end) AS ''',
      code, ''''
    )
  ) INTO @sql
FROM LOGGINGS;

SET @sql = CONCAT('SELECT date(created_at), ', @sql, '
                   FROM LOGGINGS 
                   GROUP BY date(created_at)');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Здесь - это скрипка.

0 голосов
/ 21 октября 2019

Для использования цикла внутри хранимой процедуры вы можете использовать «курсор».

Объявить курсор, который содержит требуемые данные списка

-- declare cursor
DECLARE myCursor CURSOR FOR 
     SELECT id FROM table;

-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER 
    FOR NOT FOUND SET finished = 1;

Использование:

OPEN myCursor;

getID: LOOP
    FETCH myCursor INTO myId;

    IF finished = 1 THEN 
        LEAVE getID;
    END IF;
    -- do something you want here
    .....

END LOOP getID;
CLOSE myCursor;

Ссылка здесь для получения дополнительной информации: http://www.mysqltutorial.org/mysql-cursor/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...