我正在尝试编写一个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
我想要重新创建的示例输出:
答案 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条记录均相符。
加入数据集时要非常小心,每条记录都会连接到需要的地方,并且只在需要的地方加入。
(无论如何,上面的单个解析版本应该完全避免这个问题。)