Не совсем понял почему "duration" типа "string", но если там числовые значения, то полагаю нужно нечто подобное должно дать желаемый результат:
SELECT tm "minute",
sum(CASE WHEN type = 'norm' then duration::real ELSE 0 END) "duration_norm",
sum(CASE WHEN type = 'idle' then duration::real ELSE 0 END) "duration_idle",
sum(CASE WHEN type = 'norm' then 1 ELSE 0 END) "norm",
sum(CASE WHEN type = 'idle' then 1 ELSE 0 END) "idle"
FROM generate_series('2015-01-16 17:16:00'::timestamp, '2015-01-16 18:18:00', '1 minute') tm
left join table1 t1 ON date_trunc('minute', t1.time) = tm
group by tm
ORDER BY tm