2016-12-16 2 views
2

У меня есть следующая инструкция, чтобы извлечь дату, час и количество пользователей из таблицы в базе данных Teradata. , ,Teradata - Как учесть отсутствующие часы в timestamp при использовании функции extract()

SELECT 
    CAST(end_time AS DATE) AS end_date, 
    EXTRACT(HOUR FROM end_time) AS end_hour, 
    COUNT(users) AS total_users 
FROM table 
GROUP BY end_date, end_hour 

При использовании функции экстракта(), мой ResultSet содержит недостающие часы, где нет никакой активности пользователей за 24-часовой период ... Мне интересно, есть ли метод для учета этих недостающих часов мои результаты?

Я не могу создать таблицу поиска для ссылки, поскольку у меня нет необходимых разрешений для создания таблицы в этой БД.

Любая помощь будет оценена!

+0

Что относительно отсутствующих дней? –

+0

Если вы не можете создать таблицу, вы, вероятно, можете создать временную таблицу: 'CREATE VOLATILE TABLE hours (hh BYTEINT UNIQUE NOT NULL) в COMMIT PRESERVE ROWS', а затем вставить 24 строки. – dnoeth

ответ

3
  • sys_calendar.calendar генерировать запрашиваемые даты (изменения диапазона при необходимости)
  • с рекурсивными генерировать часы

with  recursive cte_hours (hr) 
      as 
      (
          select 0  from (select 1) t(c) 
       union all select hr + 1 from cte_hours where hr < 23 
      ) 

select  c.calendar_date    as dt 
      ,h.hr      as hr 
      ,zeroifnull(t.total_users) as total_users 

from     sys_calendar.calendar as c 

      cross join cte_hours    as h 

      left join (select  cast(end_time as date)  as end_date 
            ,extract(hour from end_time) as end_hour 
            ,count(users)    as total_users 

         from  mytable t 

         group by end_date 
            ,end_hour 
         ) t 

      on   t.end_date = c.calendar_date 
        and t.end_hour = h.hr 

where  c.calendar_date between current_date - 10 and current_date  

order by dt,hr 
;  

Для @GordonLinoff

select 0 
select 1 
select 0 
union all 
select 1 

[3888] SELECT и для UNION, пересекаться или МИНУС должен ссылаться на таблицу.

select 0 from (select 1 as c) t 
union all 
select 1 from (select 1 as c) t 

или

select 0 from (select 1) t(c) 
union all 
select 1 from (select 1) t(c) 
+0

Отлично, спасибо за это Dudu, очень полезно! – Shaw

+0

при выборе дополнительного столбца из mytable t в подзапросе запрос возвращается к отсутствию отсутствующих часов ... Например, если бы я должен был выбрать дополнительную страну столбца из таблицы mytable ... Я предполагаю, что это тоже будет значение null , есть ли способ включить это в течение отсутствующих часов? – Shaw

+0

Извините, но я не понимаю –

0

Если вы хотите, чтобы все часы из всех дней в базе данных, то вы можете создать строки с помощью cross join, а затем использовать left join принести в результатах:

SELECT d.end_date, 
     EXTRACT(HOUR FROM end_time) AS end_hour, 
     COUNT(t.users) AS total_users 
FROM (select distinct CAST(end_time AS DATE) AS end_date from table) d CROSS JOIN 
    (select distinct EXTRACT(HOUR FROM end_time) AS end_hour from table) h LEFT JOIN 
    table t 
    ON t.end_date = d.end_date and t.end_hour = d.end_hour 
GROUP BY e.end_date, h.end_hour; 

Если все часы не представлены, вы можете использовать явный список:

SELECT d.end_date, 
     EXTRACT(HOUR FROM end_time) AS end_hour, 
     COUNT(t.users) AS total_users 
FROM (select distinct CAST(end_time AS DATE) AS end_date from table) d CROSS JOIN 
    (select * from (select 0 as end_hour) t UNION ALL 
     select * from (select 1 as end_hour) t UNION ALL 
     . . . 
    ) h LEFT JOIN 
    table t 
    ON t.end_date = d.end_date and t.end_hour = d.end_hour 
GROUP BY e.end_date, h.end_hour; 
+0

Второй вопрос не будет работать на Teradata –

+0

@DuduMarkovitz. , , У меня нет Терадаты под рукой. Требуется дополнительный подзапрос '(выберите * from (выберите 0 как end_hour) h union all ...)'? –

+0

См. Мой ответ (внизу) –

Смежные вопросы