Чтобы ответить на вопрос, который был задан:
Нет, в MySQL нет механизма для процедурного зацикливания нескольких значений пользовательских переменных вне хранимой программы MySQL (например, PROCEDURE of FUNCTION).
Более длинный ответ заключается в том, что нет необходимости в пользовательских переменных и циклах. Можно вернуть набор строк одним запросом, используя условное агрегирование.
(Мы отложим обсуждение нечетно отформатированного значения даты '6/28/2019'
и просто предположим, что logdate
хранится как тип данных MySQL DATE
.)
Мы можем сгенерировать строки, которые нам нужны в наборе (и приспособить неизбежные пропущенные строки, пропуская «нулевое» число), используя встроенные представления c
и e
, чтобы вернуть набор дат, которые мы хотим вернуть, Крест присоединился к списку имен сотрудников.
Встроенное представление e
здесь дает статический список из литералов, как указано в коде OP. Может потребоваться предварять литералы _latin1
или выполнять CONVERT с использованием набора символов, в котором сравнивается значение, чтобы избежать ошибки «набор символов не принудительный».
Еще лучше была бы таблица, на которую мы могли бы ссылаться, чтобы получить отдельный список имен сотрудников, и использовать запрос этой таблицы во встроенном представлении, например. SELECT ee.employee_name AS name_ FROM someothertable ee WHERE ... GROUP BY ee.employee_name
Примерно так:
SELECT e.name_
, c.date_
, COUNT(
IF( l.logmessage LIKE '%Called%'
, d.id
, NULL
)
) AS cnt_total_calls
, COUNT(
IF( l.logmessage LIKE '%Called%'
AND l.logmessage NOT LIKE '%Disconnected%'
AND l.logmessage NOT LIKE '%VM Unavailable%'
AND l.logmessage NOT LIKE '%No Answer%'
, d.id
, 0
)
) AS cnt_valid_calls
, COUNT( DISTINCT
IF( l.logmessage LIKE '%Called%'
AND l.logmessage NOT LIKE '%Disconnected%'
AND l.logmessage NOT LIKE '%VM Unavailable%'
AND l.logmessage NOT LIKE '%No Answer%'
, l.filenumber
, NULL
)
) AS cnt_total_unique_account
, MIN(
IF( l.logmessage LIKE '%Called%'
, l.logtime
, NULL
)
) AS first_call_time
, MAX(
IF( l.logmessage LIKE '%Called%'
, l.logtime
, NULL
)
) AS last_call_time
FROM (
SELECT '2019-06-28' + INTERVAL 0 DAY AS date_
) c
CROSS
JOIN (
SELECT 'Employee1' AS name_
UNION ALL SELECT 'Employee2'
UNION ALL SELECT 'Employee3'
UNION ALL SELECT 'Employee4'
UNION ALL SELECT 'Employee5'
) e
LEFT
JOIN callTrackingSoftware.log l
ON l.collectorname = e.name_
AND l.logdate = c.date_
LEFT
JOIN callTrackingSoftware.dbase d
ON d.id = l.filenumber
GROUP
BY e.name_
, c.date_
ORDER
BY e.name_
, c.date_
Обратите внимание на внешние объединения LEFT JOIN
, чтобы можно было возвращать строки для комбинаций сотрудник / логдат, где ожидается нулевое число.
Если цель объединения с d
состоит в том, чтобы исключить строки, то нам, вероятно, нужно изменить выражения условного агрегирования, чтобы они не включали строки, в которых не было совпадающей строки из d
, например,
, MAX(
IF( l.logmessage LIKE '%Called%' AND d.id IS NOT NULL
-- ^^^^^^^^^^^^^^^^^^^^
, l.logtime
, NULL
)
) AS last_call_time