Я надеюсь, что кто-то может выручить меня. У меня есть таблица, которая регистрирует наши задания импорта. Мне нужен запрос, который произведет матрицу с названиями таблиц на вертикальной оси, дат импорта на горизонтальной оси и общего количества записей, импортированных для той таблицы в ту дату в ячейке матрицы. Я не забочусь, должны ли мы составить временную таблицу, но все это должно быть сделано в MySQL.
Ниже упрощенный образец нашей таблицы журнала событий. Мало того, что это имеет намного больше fieds, но и мы импортируем намного больше таблиц. Поэтому решение должно составлять запросы имен таблиц. Вы заметите, что данные могут быть импортированы в таблицу несколько раз в день, как в записях 5 и 6.
id table_name import_date num_recs
----+-----------+--------------------+-------
0 customer 2010-06-20 00:00:00 10
1 order 2010-06-20 00:00:00 15
2 customer 2010-06-21 00:00:00 5
3 order 2010-06-21 00:00:00 6
4 customer 2010-06-22 00:00:00 1
5 order 2010-06-22 00:00:00 6
6 order 2010-06-22 00:00:00 1
Мы ищем результат что-то вроде этого. Это не должно быть точно
table_name 06-20 06-21 06-22
------------+-----+-----+------
customer | 10 | 5 | 1
order | 15 | 6 | 7
Что насчет вывода формы:
table_name date imports
------------+-------+--------
customer | 06-20 | 10
customer | 06-21 | 5
order | 06-20 | 15
order | 06-21 | 6
Таким образом, вы можете сделать это с помощью простой GROUP BY
:
SELECT table_name, DATE(import_date) AS date, SUM(*) AS imports
FROM yourTable
GROUP BY table_name, date;
В противном случае ваш запрос будет действительно противно.
Я думаю, что Ben S на правильном пути. Я хотел предложить здесь все, что мог, на случай, если это поможет кому-то, кто знает. Первоисточник
Это метод, позволяющий взять две произвольные даты и разделить их на временные блоки, а затем выполнить некоторую функцию агрегирования для других данных в каждом блоке. В вашем случае этот блок, вероятно, должен составлять один день, дата начала, вероятно, будет на 30 дней раньше текущего дня, а датой окончания, вероятно, будет текущий день. Каждый блок может быть возвращен с некоторой интересующей совокупной метрикой. В вашем случае это, скорее всего, будет SUM ('import')
SELECT t1.table_name AS имя_таблицы, t1.imports AS импортирует FROM (SELECT SUM (`import`) AS import, CEIL ((UNIX_TIMESTAMP ( '<сейчас>') - UNIX_TIMESTAMP (`import_date`)) / (<один день за? секунд, я думаю?>)) КАК ДИАПАЗОН ОТ` <ваша таблица> `WHERE` import_date` BETWEEN '<сейчас минус 30 дней> 'AND'
Это может совсем не помочь, но если да, то хорошо. Его легко изменить, чтобы он возвращал начальный день для каждого диапазона в виде столбца даты. Чтобы было ясно, это делает то же самое, что предлагает решение Ben S, но оно будет работать, если все ваши даты не 00:00:00, тогда как это приведет к тому, что его GROUP BY
в столбце даты будет fail
Чтобы увидеть, как будет выглядеть результат, просмотрите ответ Бена С. и мысленно удалите столбец даты. Однако, как я уже сказал, этот столбец можно легко добавить обратно в этот запрос.FWIW, я использовал этот метод для таблиц с более чем 4 миллионами строк, и он все еще работает менее 1 секунды, что было достаточно для моих целей.
Хэми
MySQL не может выполнять сводные запросы, но вы можете сделать это в двух запросах, используя результат первого запроса в качестве SQL для следующего запроса:
SELECT 'SELECT table_name'
UNION
SELECT CONCAT(', SUM(IF(import_date = "',import_date,'", num_recs,0)) AS "',DATE_FORMAT(import_date, "%m-%d"),'"')
FROM event_log
GROUP BY import_date
UNION
SELECT 'FROM event_log GROUP BY table_name'
Затем выполните вывод этого запроса, чтобы получить окончательные результаты, например для вашего примера вы получите:
SELECT table_name
, SUM(IF(import_date = "2010-06-20", num_recs,0)) AS "06-20"
, SUM(IF(import_date = "2010-06-21", num_recs,0)) AS "06-21"
, SUM(IF(import_date = "2010-06-22", num_recs,0)) AS "06-22"
FROM event_log GROUP BY table_name
Вы можете либо написать хранимую процедуру для объединения, подготовки, а затем выполнить результаты первого запроса, ИЛИ, если все это выполняется из сценария оболочки, вы можете захватить результаты первый запрос, а затем верните результаты в mysql.