Oracle SQL 聚合功能
Oracle SQL aggregate functionality
我有一个脚本:
select
regexp_replace(b.username, '[0-9]', '') username, a.wait_class, count(*)
from
v$active_session_history a, dba_users b
where
a.user_id=b.user_id and
a.sample_time>sysdate - &minutes/1440
group by
regexp_replace(b.username, '[0-9]', ''), a.wait_class
order by
3 desc
它的输出是这样的:
USERNAME WAIT_CLASS COUNT(*)
UMESS Commit 139
VITPOINT User I/O 126
VITPOINT <NULL> 69
如何将其分解为 HOURLY 段,以便输出如下所示:
USERNAME START TIME WAIT_CLASS COUNT(*)
UMESS 10:00:00 Commit 66
UMESS 11:00:00 Commit 73
VITPOINT 10:00:00 User I/O 62
VITPOINT 11:00:00 User I/O 64
etc
我希望间隔是以分钟为单位输入的 & 变量。因此,如果输入 60 分钟,则间隔为每小时,例如。
谢谢
这是一个很好的挑战。我使用数字生成器生成最大和最小采样时间之间的序列。使用 &bucket_minutes
变量以分钟为单位提供间隔。
with cte_basedata as (
select regexp_replace(u.username, '[0-9]', '') username, ash.wait_class, ash.sample_time
from v$active_session_history ash
join dba_users u on (ash.user_id = u.user_id)
where ash.sample_time>sysdate - &minutes/1440
), cte_ng as (
select (sysdate - (level-1) / 24 / 60 * &bucket_minutes) bucket_end, (sysdate - (level) / 24 / 60 * &bucket_minutes) bucket_start
from dual
connect by level <= (select extract (day from (max(sample_time) - min(sample_time)) * 24 * 60) / &bucket_minutes + 1 from cte_basedata)
), cte_data as (
select d.*, cte_ng.bucket_start
from cte_basedata d
left outer join cte_ng on (d.sample_time between cte_ng.bucket_start and cte_ng.bucket_end)
)
select username, wait_class, bucket_start, count(*) from cte_data
group by username, wait_class, bucket_start
这里有一种方法可以满足您的需求:
select
regexp_replace(b.username, '[0-9]', '') username, a.wait_class,
to_char( round( ( a.sample_time - trunc( a.sample_time ) ) * (24*(60/&minutes)) )/ (24*(60/&&minutes)) + trunc( a.sample_time ), 'HH24:MI:SS' ) start_time, -- Used to round the time to the nearest XX minutes
count(*)
from
v$active_session_history a, dba_users b
where
a.user_id=b.user_id and
a.sample_time>sysdate - &&minutes/1440
group by
regexp_replace(b.username, '[0-9]', ''), a.wait_class, to_char( round( ( a.sample_time - trunc( a.sample_time ) ) * (24*(60/&minutes)) )/ (24*(60/&&minutes)) + trunc( a.sample_time ), 'HH24:MI:SS' )
order by
3 desc;
问题是你说:
I would like the interval to be an & variable entered in minutes. So if 60 minutes is the input, then the interval is hourly, for example.
问题是,如果您想要例如 30 分钟的间隔,那么在您的 where 子句中您只需要最后 30 分钟,那么每个 user/wait_class.
将只有两行
所以你需要像这样添加第二个参数:
SELECT regexp_replace(b.username, '[0-9]', '') username,
a.wait_class,
to_char( round( ( cast(a.sample_time as date) - trunc( cast(a.sample_time as date) ) ) * (24*(60/
&&minutes)) ) / (24*(60/
&&minutes)) + TRUNC( CAST(a.sample_time AS DATE) ), 'HH24:MI:SS' ) start_time, -- Used to round the time to the nearest XX minutes
COUNT( *)
FROM v$active_session_history a,
dba_users b
WHERE a.user_id =b.user_id
and a.sample_time>sysdate -
&&from_minutes /1440
GROUP BY regexp_replace(b.username, '[0-9]', ''),
a.wait_class,
to_char( round( ( cast(a.sample_time as date) - trunc( cast(a.sample_time as date) ) ) * (24*(60/
&&minutes)) ) / (24*(60/
&&minutes)) + TRUNC( CAST(a.sample_time AS DATE) ), 'HH24:MI:SS' )
ORDER BY 3 DESC;
希望对您有所帮助
此致
我有一个脚本:
select
regexp_replace(b.username, '[0-9]', '') username, a.wait_class, count(*)
from
v$active_session_history a, dba_users b
where
a.user_id=b.user_id and
a.sample_time>sysdate - &minutes/1440
group by
regexp_replace(b.username, '[0-9]', ''), a.wait_class
order by
3 desc
它的输出是这样的:
USERNAME WAIT_CLASS COUNT(*)
UMESS Commit 139
VITPOINT User I/O 126
VITPOINT <NULL> 69
如何将其分解为 HOURLY 段,以便输出如下所示:
USERNAME START TIME WAIT_CLASS COUNT(*)
UMESS 10:00:00 Commit 66
UMESS 11:00:00 Commit 73
VITPOINT 10:00:00 User I/O 62
VITPOINT 11:00:00 User I/O 64
etc
我希望间隔是以分钟为单位输入的 & 变量。因此,如果输入 60 分钟,则间隔为每小时,例如。
谢谢
这是一个很好的挑战。我使用数字生成器生成最大和最小采样时间之间的序列。使用 &bucket_minutes
变量以分钟为单位提供间隔。
with cte_basedata as (
select regexp_replace(u.username, '[0-9]', '') username, ash.wait_class, ash.sample_time
from v$active_session_history ash
join dba_users u on (ash.user_id = u.user_id)
where ash.sample_time>sysdate - &minutes/1440
), cte_ng as (
select (sysdate - (level-1) / 24 / 60 * &bucket_minutes) bucket_end, (sysdate - (level) / 24 / 60 * &bucket_minutes) bucket_start
from dual
connect by level <= (select extract (day from (max(sample_time) - min(sample_time)) * 24 * 60) / &bucket_minutes + 1 from cte_basedata)
), cte_data as (
select d.*, cte_ng.bucket_start
from cte_basedata d
left outer join cte_ng on (d.sample_time between cte_ng.bucket_start and cte_ng.bucket_end)
)
select username, wait_class, bucket_start, count(*) from cte_data
group by username, wait_class, bucket_start
这里有一种方法可以满足您的需求:
select
regexp_replace(b.username, '[0-9]', '') username, a.wait_class,
to_char( round( ( a.sample_time - trunc( a.sample_time ) ) * (24*(60/&minutes)) )/ (24*(60/&&minutes)) + trunc( a.sample_time ), 'HH24:MI:SS' ) start_time, -- Used to round the time to the nearest XX minutes
count(*)
from
v$active_session_history a, dba_users b
where
a.user_id=b.user_id and
a.sample_time>sysdate - &&minutes/1440
group by
regexp_replace(b.username, '[0-9]', ''), a.wait_class, to_char( round( ( a.sample_time - trunc( a.sample_time ) ) * (24*(60/&minutes)) )/ (24*(60/&&minutes)) + trunc( a.sample_time ), 'HH24:MI:SS' )
order by
3 desc;
问题是你说:
I would like the interval to be an & variable entered in minutes. So if 60 minutes is the input, then the interval is hourly, for example.
问题是,如果您想要例如 30 分钟的间隔,那么在您的 where 子句中您只需要最后 30 分钟,那么每个 user/wait_class.
将只有两行所以你需要像这样添加第二个参数:
SELECT regexp_replace(b.username, '[0-9]', '') username,
a.wait_class,
to_char( round( ( cast(a.sample_time as date) - trunc( cast(a.sample_time as date) ) ) * (24*(60/
&&minutes)) ) / (24*(60/
&&minutes)) + TRUNC( CAST(a.sample_time AS DATE) ), 'HH24:MI:SS' ) start_time, -- Used to round the time to the nearest XX minutes
COUNT( *)
FROM v$active_session_history a,
dba_users b
WHERE a.user_id =b.user_id
and a.sample_time>sysdate -
&&from_minutes /1440
GROUP BY regexp_replace(b.username, '[0-9]', ''),
a.wait_class,
to_char( round( ( cast(a.sample_time as date) - trunc( cast(a.sample_time as date) ) ) * (24*(60/
&&minutes)) ) / (24*(60/
&&minutes)) + TRUNC( CAST(a.sample_time AS DATE) ), 'HH24:MI:SS' )
ORDER BY 3 DESC;
希望对您有所帮助
此致