2017-02-06 2 views
0

В настоящее время у меня есть следующие необработанные данные в redshift.Временной интервал Redshift GROUP BY

timestamp     ,lead 
================================== 
"2008-04-09 10:02:01.000000",true 
"2008-04-09 10:03:05.000000",true 
"2008-04-09 10:31:07.000000",true 
"2008-04-09 11:00:05.000000",false 
... 

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

timestamp     ,count 
================================== 
"2008-04-09 10:00:00.000000",2 
"2008-04-09 10:30:00.000000",1 
"2008-04-09 11:00:00.000000",0 
... 

я упомянул https://stackoverflow.com/a/12046382/3238864, который действителен для PostgreSQL.

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

with thirty_min_intervals as (
    select 
     (select min(timestamp)::date from events) + (n || ' minutes')::interval start_time, 
     (select min(timestamp)::date from events) + ((n+30) || ' minutes')::interval end_time 
    from generate_series(0, (24*60), 30) n 
) 
select count(CASE WHEN lead THEN 1 END) from events e 
right join thirty_min_intervals f 
on e.timestamp >= f.start_time and e.timestamp < f.end_time 
group by f.start_time, f.end_time 
order by f.start_time; 

Однако я получаю ошибку

[0A000] ERROR: Specified types or functions (one per INFO message) not supported on Redshift tables. 

Могу ли я узнать, что это хороший способ для выполнения расчета данных агрегации, от N интервала, в redshift.

+0

Amazon-красное смещение не поддерживает 'generate_series()' функцию. [Обратите внимание, что для неподдерживаемых функций postgresql] (http://docs.aws.amazon.com/redshift/latest/dg/c_unsupported-postgresql-functions.html) – Viki888

+0

Но если вы запустили голую команду 'select * from generate_series (0 , (24 * 60), 30) n; 'в красном смещении, он работает нормально. –

+0

Да. 'Generate_series' будет работать в родительском узле. Если вы попытаетесь получить доступ к таблице красного смещения в запросе, у которого есть generate_series, она проведет через вас эту ошибку, поскольку дочерний узел не будет поддерживать функцию generate_series(). Если ваш запрос не имеет доступа к таблицам красного смещения, функция generate_series() даст вам результат. – Viki888

ответ

1

Вы можете использовать ROW_NUMBER() для генерации серии. Я использую внутренние таблицы, которые, как я знаю, являются большими. FWIW, я бы, как правило, сохранял time_dimension в реальной таблице, чтобы избежать повторения этого.

Здесь вы идете:

WITH events 
AS (   SELECT '2017-02-16 10:02:01'::timestamp as ts, true::boolean as lead 
    UNION ALL SELECT '2017-02-16 10:03:05'::timestamp as ts, true::boolean as lead 
    UNION ALL SELECT '2017-02-16 10:31:07'::timestamp as ts, true::boolean as lead 
    UNION ALL SELECT '2017-02-16 11:00:05'::timestamp as ts, false::boolean as lead) 

,time_dimension 
AS (SELECT dtm 
      ,dtm - ((DATEPART(SECONDS,dtm) + (DATEPART(MINUTES,dtm)*60) % 1800) * INTERVAL '1 second') AS dtm_half_hour 
    FROM /* Create a series of timestamp. 1 per second working backwards from NOW(). */ 
     /* NB: `sysdate` could be substituted for an arbitrary ending timestamp */ 
     (SELECT DATE_TRUNC('SECONDS',sysdate) - (n * INTERVAL '1 second') AS dtm 
      FROM /* Generate a number sequence of 100,000 values from a large internal table */ 
       (SELECT ROW_NUMBER() OVER() AS n FROM stl_scan LIMIT 100000) rn) rn) 

SELECT dtm_half_hour 
     ,COUNT(CASE WHEN lead THEN 1 END) 
FROM  time_dimension td 
LEFT JOIN events e 
     ON td.dtm = e.ts 
WHERE td.dtm_half_hour BETWEEN '2017-02-16 09:30:00' AND '2017-02-16 11:00:00' 
GROUP BY 1 
ORDER BY 1 
; 
Смежные вопросы