我有一个包含警报历史记录的表,其中包含开始日期,结束日期和警报原因。
我希望最近30天的每个日期都可以计算当天发生的警报总数,这意味着如果警报从第1天开始并且仍在持续(结束日期为空),则它将计算从该天起的所有天数1倒数。
这是我提出的查询
select cal.trunc_date,assets.group_id,
alert.*,
count( alert.asset_id)
over (PARTITION BY alert.REASON_ID ORDER BY
cal.trunc_date) TOTAL_ASSETS
from g_alert_history alert,
v_app_calendar cal,V_ACTIVE_ASSETS assets
where REASON_ID in (1,2)
and assets.asset_id=alert.asset_id
and assets.group_id=1462
and cal.trunc_date >= trunc(systimestamp - 30)
and alert.START_DATE_DEVICE >= trunc(systimestamp - 30)
and alert.START_DATE_DEVICE >= cal.trunc_date
and alert.START_DATE_DEVICE <= cal.trunc_date +1
and nvl (alert.END_DATE_DEVICE, systimestamp)
>=cal.trunc_date;
视图v_app_calendar
包含日期,而V_ACTIVE_ASSETS
包含我要检查的group_id
。
问题是我得到重复,重复等
这是结果:
TRUNC_DATE GROUP_ID REASON_ID ASSET_ID GEOFENCE_ID START_DATE_DEVICE END_DATE_DEVICE TOTAL_ASSETS
--------- -------- --------- -------- ----------- ------------------------------- ------------------------------- ------------
03-FEB-19 1462 1 1704 134 03-FEB-19 11.50.09.385000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.55.09.475000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 12.00.10.073000000 PM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 12.05.11.126000000 PM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 12.10.12.668000000 PM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 12.15.12.858000000 PM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.45.09.283000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.20.03.587000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.25.05.434000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.30.07.294000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.35.09.141000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 11.40.09.251000000 AM 13
03-FEB-19 1462 1 1704 134 03-FEB-19 12.20.14.178000000 PM 13
05-FEB-19 1462 1 1663 134 05-FEB-19 02.33.02.475000000 PM 14
09-FEB-19 1462 1 1663 134 09-FEB-19 09.33.02.475000000 PM 09-FEB-19 11.33.22.475000000 PM 16
09-FEB-19 1462 1 1782 149 09-FEB-19 02.33.02.475000000 PM 09-FEB-19 02.36.02.475000000 PM 16
11-FEB-19 1462 1 2647 134 11-FEB-19 09.56.08.325000000 AM 140
11-FEB-19 1462 1 2647 164 11-FEB-19 09.56.08.325000000 AM 140
11-FEB-19 1462 1 2646 164 11-FEB-19 10.03.31.611000000 AM 140
11-FEB-19 1462 1 2646 134 11-FEB-19 10.03.31.611000000 AM 140
11-FEB-19 1462 1 1781 164 11-FEB-19 10.14.09.612000000 AM 140
11-FEB-19 1462 1 2647 134 11-FEB-19 11.55.20.281000000 AM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 10.14.09.612000000 AM 140
11-FEB-19 1462 1 2647 164 11-FEB-19 10.55.32.300000000 AM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 02.52.45.104000000 PM 140
11-FEB-19 1462 1 1781 164 11-FEB-19 03.20.40.461000000 PM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 03.20.40.461000000 PM 140
11-FEB-19 1462 1 1781 164 11-FEB-19 08.28.13.331000000 PM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 08.28.13.331000000 PM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 03.20.42.461000000 PM 140
11-FEB-19 1462 1 1781 134 11-FEB-19 08.28.25.939000000 PM 140
11-FEB-19 1462 1 1781 164 11-FEB-19 08.28.25.939000000 PM 140
答案 0 :(得分:0)
如果您需要日间的数据,则必须在将时间戳列转换为日期后再应用与之不同的子句。
类似下面的东西-
select cal.trunc_date,assets.group_id,
alert.req_col,
cast(alert.start_date_device as date),
cast(alert.end_date_device as date)
count( alert.asset_id)
over (PARTITION BY alert.REASON_ID ORDER BY
cal.trunc_date) TOTAL_ASSETS
from g_alert_history alert,
v_app_calendar cal,V_ACTIVE_ASSETS assets
where REASON_ID in (1,2)
and assets.asset_id=alert.asset_id
and assets.group_id=1462
and cal.trunc_date >= trunc(systimestamp - 30)
and alert.START_DATE_DEVICE >= trunc(systimestamp - 30)
and alert.START_DATE_DEVICE >= cal.trunc_date
and alert.START_DATE_DEVICE <= cal.trunc_date +1
and nvl (alert.END_DATE_DEVICE, systimestamp)
>=cal.trunc_date;
您提供的数据不是重复的,因为它包含每个记录的唯一时间戳。
希望这会有所帮助
答案 1 :(得分:0)
尝试以下代码。
“日期”表包含过去30天(包括今天)的所有日期。
我还将您的JOIN
语法更改为一种新的形式。
with dates as (
select trunc(sysdate) - (level - 1) trunc_date from dual connect by level<=30
)
select dates.trunc_date
, count(alert.asset_id)
from g_alert_history alert
join v_app_calendar cal
on (alert.START_DATE_DEVICE between cal.trunc_date and (cal.trunc_date +1)
and nvl (alert.END_DATE_DEVICE, systimestamp) >= cal.trunc_date )
join V_ACTIVE_ASSETS assets
on (assets.asset_id=alert.asset_id)
where REASON_ID in (1,2)
and dates.trunc_date between trunc(alert.START_DATE_DEVICE) and nvl(alert.END_DATE_DEVICE, trunc(sysdate))
and cal.trunc_date >= trunc(systimestamp - 30)
and assets.group_id=1462
group by dates.trunc_date
希望我能帮上忙!
答案 2 :(得分:0)
由于您希望对当天发生的所有警报进行每日计数(警报可能在前一天开始,或在以后的一天结束),因此您要使用按天分组的汇总计数(可能还有其他条件),而不是查询中显示的分析计数。要在给定的一天中没有过多重复执行汇总,您需要消除提供非唯一值的列。主要是您的警报开始和结束日期,以及asset_id
和geofence_id
。
下面的查询将为您提供请求的group_id
和reason_id
在最近30天内发生的变更次数。
select cal.trunc_date
, assets.group_id
, alert.reason_id
, count( alert.asset_id) TOTAL_ASSETS
from g_alert_history alert
join V_ACTIVE_ASSETS assets
on assets.asset_id=alert.asset_id
join v_app_calendar cal
on alert.START_DATE_DEVICE < cal.trunc_date + 1
and (alert.END_DATE_DEVICE is null or cal.trunc_date <= alert.END_DATE_DEVICE)
where alert.REASON_ID in (1,2)
and assets.group_id=1462
and cal.trunc_date between trunc(sysdate - 30) and sysdate
group by cal.trunc_date
, assets.group_id
, alert.reason_id
order by cal.trunc_date
, assets.group_id
, alert.reason_id;