Oracle - SQL,从日期范围内拉动时间

时间:2011-10-20 15:04:43

标签: sql oracle date time

我正在尝试编写一个select语句来返回特定日期范围内特定时间范围内的平均值。例如,我想知道在下午4点到11点,全天和上午8点到下午6点的时间段内过去7天的平均值(max_percent_util)。这是我到目前为止所做的,我不确定查询是否会在此时结束。

select 
sdpt.DOWN_DESC, 
avg(sdpt.max_percent_util) seven_day_prime,
avg(sday.max_percent_util) seven_day,
avg(sdb.max_percent_util) seven_day_business

from 

(select down_desc, hour_stamp, max_percent_util from downstream_hour_facts 
where ((hour_stamp >= sysdate-8 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-7 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-6 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-5 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-4 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-3 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-2 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00')
or (hour_stamp >= sysdate-1 AND to_char(hour_stamp, 'HH24:MI') >= '16:00' AND to_char(hour_stamp, 'HH24:MI') <= '23:00'))) sdpt,

(select down_desc, hour_stamp, max_percent_util from downstream_hour_facts 
where ((hour_stamp >= sysdate-8) or (hour_stamp >= sysdate-7) or (hour_stamp >= sysdate-6)
or (hour_stamp >= sysdate-5) or (hour_stamp >= sysdate-4) or (hour_stamp >= sysdate-3)
or (hour_stamp >= sysdate-2) or (hour_stamp >= sysdate-1))) sday,

(select down_desc, hour_stamp, max_percent_util from downstream_hour_facts 
where ((hour_stamp >= sysdate-8 AND to_char(hour_stamp, 'HH24:MI') >= '8:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-7 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-6 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-5 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-4 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-3 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-2 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00')
or (hour_stamp >= sysdate-1 AND to_char(hour_stamp, 'HH24:MI') >= '08:00' AND to_char(hour_stamp, 'HH24:MI') <= '18:00'))) sdb
where sdpt.down_desc = sday.down_desc and sday.down_desc = sdb.down_desc
group by sdpt.DOWN_DESC
order by sdpt.down_desc

我想要重新创建的示例输出:

  • 指标:利用率数据
  • 过去24小时:7.15%
  • 7天滚动(所有小时):7.12%
  • 7天滚动黄金时间(4-12):7.12%
  • 7天滚动营业时间(9-5):7.12%

1 个答案:

答案 0 :(得分:3)

你的查询速度慢的一个原因是你不是在盯住日期,而是在比较字符串;使用TO_CHAR()。你也做了很多多余的工作。

这是一个解析数据一次(而不是三次)的示例,避免了字符串比较,因此应该快速将数据过滤到8和你想要的几天。

WITH
  filtered_data AS
(
  SELECT
    down_desc,
    hour_stamp,
    TRUNC(hour_stamp)                date_stamp,
    hour_stamp - TRUNC(hour_stamp)   time_stamp
  FROM
    downstream_hour_facts
  WHERE
    hour_stamp >= TRUNC(sysdate) - 8
)
SELECT
  down_desc,
  AVG(CASE WHEN date_stamp >= TRUNC(sysdate)
           THEN max_percent ELSE NULL END)          today,
  AVG(CASE WHEN date_stamp <  TRUNC(sysdate)
           THEN max_percent ELSE NULL END)          seven_day_all,
  AVG(CASE WHEN date_stamp <  TRUNC(sysdate)
            AND time_stamp >= TO_TIMESTAMP('16:00', 'HH24:MI')
            AND time_stamp <  TO_TIMESTAMP('23:00', 'HH24:MI')
           THEN max_percent ELSE NULL END)          seven_day_prime,
  AVG(CASE WHEN date_stamp <  TRUNC(sysdate)
            AND time_stamp >= TO_TIMESTAMP('08:00', 'HH24:MI')
            AND time_stamp <  TO_TIMESTAMP('16:00', 'HH24:MI')
           THEN max_percent ELSE NULL END)          seven_day_business
FROM
  filtered_data
GROUP BY
  down_desc
ORDER BY
  down_desc


修改

我也注意到你以“危险'错误的方式加入数据......

子查询1可以返回指标的9条记录。 子查询2可以返回该度量的3条记录。 子查询3可以返回该度量的4条记录。

但是您按照指标加入。 SQ1的所有9条记录与SQ2的所有3条记录(现在27条记录)相符,所有这些记录与SQ3(现在有108条记录)的所有4条记录均相符。

加入数据集时要非常小心,每条记录都会连接到需要的地方,并且只在需要的地方加入。

(无论如何,上面的单个解析版本应该完全避免这个问题。)