【问题标题】:aggregating Data by Time Interval in Oracle SQL在 Oracle SQL 中按时间间隔聚合数据
【发布时间】:2014-03-09 23:51:42
【问题描述】:

我有一个天气温度数据数据集,每 5 分钟记录一次。我想将其汇总为 15 分钟的数据。为此,我需要按日期、小时和分钟对时间间隔进行分组,因此对于分钟,我是在以下分钟间隔 {5、10、15}、{20、25、30}、{35、 40, 45}, {50, 55, 60}。对于每组三个读数,我应该取平均值。

我的数据有一个“DD-MMM-YY HH.MM”形式的时间戳,所以我提取了日期、小时和分钟。我写了一个案例来对时间戳进行分组,但效果不太好,我不确定如何将平均函数构建到案例中。

  Select
  Temperature,
  Extract(Minute From Reading_Time) As Minutes,
  Extract(Hour From Reading_Time) As Hours,
  Cast(Reading_Time As Date) As Calendar_Date
  From Weather_Data Where Weather_Station='BDX'    
  Case
    When (Minutes>5 And Minutes<=15)  Then
    To_Timestamp(Calendar_Date &' '&'0'&Hours&':15', 'dd-mon-yy hh24:mi')
    When (Minutes>20 And Minutes<=30)  Then
    To_Timestamp(Calendar_Date &' '&'0'&Hours&':30', 'dd-mon-yy hh24:mi')
    When (Minutes>35 And Minutes<=45)  Then
    To_Timestamp(Calendar_Date &' '&'0'&Hours&':45', 'dd-mon-yy hh24:mi')
    When (Minutes>50 And Minutes<=60)  Then
    To_Timestamp(Calendar_Date &' '&'0'&Hours&':60', 'dd-mon-yy hh24:mi')
End

根据 Gordon 的反馈修改代码。我还重写了案例逻辑以纠正时间上的轻微偏移。

select t.*,
(Case When Minutes <= 15 AND Minutes > 0
         Then To_Timestamp(Calendar_Date  &' '&Hours&':15', 'dd-mon-yy hh24:mi')
         When Minutes <= 30 AND Minutes > 0
         Then To_Timestamp(Calendar_Date &' '&Hours&':30', 'dd-mon-yy hh24:mi')
         When Minutes <= 45 AND Minutes > 0
         Then To_Timestamp(Calendar_Date &' '&Hours&':45', 'dd-mon-yy hh24:mi')
         When Minutes = 0 
         Then To_Timestamp(Calendar_Date &' '&Hours&':00', 'dd-mon-yy hh24:mi')
         Else To_Timestamp(Calendar_Date &' '&(Hours+1)&':00', 'dd-mon-yy hh24:mi')
   End) As Aggregated_Timestamp
 from (Select average(Temperature), Extract(Minute From Reading_Time) As Minutes,
         Extract(Hour From Reading_Time) As Hours, Cast(Reading_Time As Date) As    Calendar_Date
  From Weather_Data
  Where Weather_Station = 'BDX'
  Group by Aggregated_Time
 ) t 

【问题讨论】:

    标签: sql aggregation


    【解决方案1】:

    您的case 只是在您的查询后徘徊。最简单的编写方法是使用子查询:

    select t.*,
           (Case When (Minutes>5 And Minutes<=15) 
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':15', 'dd-mon-yy hh24:mi')
                 When (Minutes>20 And Minutes<=30)
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':30', 'dd-mon-yy hh24:mi')
                 When (Minutes>35 And Minutes<=45)
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':45', 'dd-mon-yy hh24:mi')
                 When (Minutes>50 And Minutes<=60)
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':60', 'dd-mon-yy hh24:mi')
           End)
    from (Select Temperature, Extract(Minute From Reading_Time) As Minutes,
                 Extract(Hour From Reading_Time) As Hours, Cast(Reading_Time As Date) As Calendar_Date
          From Weather_Data
          Where Weather_Station = 'BDX'
         ) t 
    

    我不完全理解你的逻辑,因为你有差距。我只想写:

           (Case When Minutes <= 15
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':15', 'dd-mon-yy hh24:mi')
                 When Minutes <= 30
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':30', 'dd-mon-yy hh24:mi')
                 When Minutes <= 45
                 Then To_Timestamp(Calendar_Date &' '&'0'&Hours&':45', 'dd-mon-yy hh24:mi')
                 else To_Timestamp(Calendar_Date &' '&'0'&Hours&':60', 'dd-mon-yy hh24:mi')
           End)
    

    【讨论】:

    • 这很有帮助,戈登!我唯一仍在苦苦挣扎的事情就是为时间戳获取一个不同的条目,并对共享一个聚合时间戳的三个温度值进行平均。我修改了我在上面的代码中尝试的内容。
    • 您需要按case 语句的结果进行分组。根据 SQL 引擎,您可以在 group by 子句中重复整个表达式、使用列名或使用子查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2014-06-17
    相关资源
    最近更新 更多