Teradata - 使用 extract() 函数时如何计算时间戳中缺失的小时数

Teradata - How to account for missing hours in timestamp when using extract() function

我有以下语句从 Teradata DB 中的 table 中提取日期、小时和用户数。 . .

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

当使用 extract() 函数时,我的结果集包含缺失的时间,其中用户在 24 小时内没有 activity...我想知道是否有任何技术可以解决这些缺失我的结果集中有几个小时?

我无法创建查找 table 以供参考,因为我没有必要的权限在此数据库上创建 table。

如有任何帮助,我们将不胜感激!

如果您想要数据库中所有日期的所有时间,那么您可以使用 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;
  • 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

0

select 1

1

select 0
union all
select 1

[3888] A SELECT for a UNION,INTERSECT or MINUS must reference a table.

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

0
1

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

0
1