2012-05-28 2 views
1

Мне нужно создать отчет о количестве заданий, выполняемых в день и в час. Таким образом, отчет будет выглядеть как сетка.Выбор ежедневных/почасовых данных

Я хотел бы, чтобы дни месяца (от 1 до 31) были горизонтальной осью и часами (с 8:00 до 18:00) по вертикали.

Как выбрать этот вид данных из базы данных с использованием SQL в PostgreSQL?

+0

Пусть я таблица называется «задача» с идентификатором поля, date_time_of_task, fk_who_did_it –

+0

Сделали вы либо 'заявление SELECT' в SQL раньше? Если вы знаете, как устроить сетку, то вы на полпути. Попытайтесь понять логику, используемую для ее построения. Я предлагаю сделать несколько широких запросов и опубликовать ваши попытки, затем другие могут прийти и помочь вам уточнить ваш запрос для создания отчета. Вы должны хотя бы приложить некоторые усилия! – Zairja

+0

Я знаю немного SQL ... проблема в том, как отделить результаты за час? Я никогда не делал этого раньше =/ –

ответ

1

Запрос, который вы ищете, представляет собой запрос агрегации SQL. Это может показаться немного сложным, но структура довольно проста.

select extract(hour from date_time_of_task) as thehour, 
     sum(case when extract(day from date_time_of_task) = 1 then 1 else 0 end) as day_01, 
     sum(case when extract(day from date_time_of_task) = 2 then 1 else 0 end) as day_02, 
     sum(case when extract(day from date_time_of_task) = 3 then 1 else 0 end) as day_03, 
     sum(case when extract(day from date_time_of_task) = 4 then 1 else 0 end) as day_04, 
     ... up to day 31 
group by extract(hour from date_time_of_task) 
order by 1 

Это просто группировка по часам дня. Затем он поворачивает данные вручную для каждого дня месяца. «Сумма» подсчитывает количество строк, которые соответствуют двум условиям одновременно - час строки и день столбца.

+0

Хорошо, я протестировал оба пути и получил ожидаемые результаты. Спасибо! знак равно –

1

ключевых элементов элегантного решения являются generate_series(), date_part(), A CTE, GROUP BY и count(*), LEFT JOIN и последнее: crosstab() функция (с 1 параметром) из дополнительного модуля tablefunc. Чтобы установить его, запустить раз в базе данных:

CREATE EXTENSION tablefunc; 

запрос:

SELECT * 
FROM crosstab($x$ 

WITH x AS (
    SELECT date_part('day', date_time_of_task)::int AS d 
      ,date_part('hour', date_time_of_task)::int AS h 
      ,count(*)::int AS ct 
    FROM tasks 
    GROUP BY 1,2 
    ) 
SELECT d, h, ct 
FROM (SELECT generate_series(1,31) AS d, generate_series(0,23) AS h) t 
LEFT JOIN x USING (d,h) 
ORDER BY 1,2 

$x$) 
AS orders(
day int 
,h8 int, h9 int, h10 int, h11 int, h12 int, h13 int, h14 int, h15 int 
,h16 int, h17 int, h18 int); 

производит матрицу дней и часов с графом задач в каждой области, как вы описали.

BTW: Я использовал этот aux. Функция для создания списка определений цели:

SELECT 'day int, ' || string_agg (x, ', ') 
FROM (SELECT ('h' || generate_series(8,18) || ' int') AS x) a