Reputation: 302
Issue Description: I have the following query to retrieve the latest alarms in last 15 minutes.
SELECT
AlmCode,OccurTime,ClearTime....columnN
FROM
TB_ALM
WHERE
AlmCode IN ('3236',....'5978') AND
OccurTime >= date_sub(NOW(),interval 15 minute);
Table Structure:
CREATE TABLE `TB_ALM` (
`Col1` smallint(2) DEFAULT NULL,
`Col2` int(4) DEFAULT NULL,
`Col3` int(2) DEFAULT NULL,
`Col4` int(10) DEFAULT NULL,
`Col5` int(10) unsigned DEFAULT NULL,
`Col6` int(2) DEFAULT NULL,
`Col7` int(2) DEFAULT NULL,
`Col8` int(10) DEFAULT NULL,
`Col9` int(10) unsigned DEFAULT NULL,
`AlmCode` int(10) unsigned DEFAULT NULL,
`Col10` int(2) NOT NULL,
`Col11` int(10) unsigned DEFAULT NULL,
`Col12` char(12) DEFAULT NULL,
`Col13` int(2) unsigned DEFAULT NULL,
`Col14` int(10) unsigned DEFAULT NULL,
`Col15` int(10) unsigned DEFAULT NULL,
`Col16` int(10) unsigned DEFAULT NULL,
`OccurTime` datetime NOT NULL,
`ClearTime` datetime DEFAULT NULL,
`AlmDesc` varchar(500) DEFAULT NULL,
`Col20` int(1) DEFAULT '0',
`Col21` bigint(20) DEFAULT NULL,
`Col22` char(120) DEFAULT NULL,
`Col23` int(10) DEFAULT NULL,
KEY `TB_ALM_IDX2` (`Col1`,`Col2`,`Col3`,`Col6`,`Col7`,`Col11`,`AlmCode`,`Col9`,`Col4`,`Col8`,`ClearTime`) USING BTREE,
KEY `TB_ALM_IDX1` (`Col1`,`Col2`,`Col3`,`Col6`,`Col7`,`Col11`,`AlmCode`,`Col5`,`Col21`),
KEY `TB_ALM_IDX3` (`Col1`,`Col2`,`Col3`,`Col5`) USING BTREE,
KEY `TB_ALM_IDX4` (`Col1`,`Col2`,`Col3`,`OccurTime`,`ClearTime`,`Col21`) USING BTREE,
KEY `TB_ALM_IDX5` (`Col23`),
KEY `TB_ALM_IDX6` (`Col1`,`Col2`,`Col3`,`Col6`,`Col7`,`AlmCode`,`Col11`,`ClearTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
What's Needed: Now I want to have this modified to retrieve the alarms with following criteria:
a. Alarms(AlmCodes) occurred in last 15 minutes(Original Req) AND
b. ONLY If each of Alarms(AlmCodes) has not occurred more than thrice in any of the 15 minute window during last six hours
What's Tried: I tried the following approach:
Get the DISTINCT(AlmCodes) during last 15 minutes.
select distinct(AlmCode) from TB_ALM where AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978') AND OccurTime >= date_sub(NOW(),interval 15 minute) ;
Use Item-1(above) as subquery and get the count of occurrence for each AlmCode.
select Almcode,concat(date(OccurTime),' ',HOUR(OccurTime)) as HR,count(*) from TB_ALM_HISTORY where AlmCode IN ( select distinct(s.AlmCode) from TB_ALM_HISTORY s where s.AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978') AND s.OccurTime >= date_sub(NOW(),interval 15 minute) ) AND OccurTime >= date_sub(NOW(),interval 15*4*24 minute) group by AlmCode,HR;
Issues:
Query-1: Get unique alarms
select distinct(AlmCode)
from TB_ALM_HISTORY
where AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978')
AND OccurTime >= date_sub(NOW(),interval 15 minute) ;
+---------+
| AlmCode |
+---------+
| 3236 |
| 5202 |
| 5236 |
+---------+
Query-2: Get the count for each of unique alarms for last 6 hours
select Almcode,concat(date(OccurTime),' ',LPAD(HOUR(OccurTime),2,'0')) as HR,count(*) from TB_ALM_HISTORY where AlmCode IN ('3236','5202','5236') AND OccurTime >= date_sub(NOW(),interval 15*4*7 minute) group by AlmCode,HR;
+---------+---------------+----------+
| Almcode | HR | count(*) |
+---------+---------------+----------+
| 3236 | 2015-08-04 11 | 2 |
| 5202 | 2015-08-04 13 | 6 |
| 5202 | 2015-08-04 14 | 4 |
| 5202 | 2015-08-04 15 | 2 |
| 5202 | 2015-08-04 16 | 1 |
| 5202 | 2015-08-04 17 | 2 |
+---------+---------------+----------+
Assuming this query was run at 6PM EST, AlmCode 5202 has occurred in last 6 hours(btwn 12-18Hours) and hence results for this AlmCode should not be included in the final select query(of occurred in last 15 minutes). whereas AlmCode 3236 didn't occur in last 6 hours and hence all the alarms that occured in last 15 minutes for this particular AlmCode have to be included.
a. Get the unique AlmCode with OccurTime >= Last 15 Minutes
b. For each of these AlmCode, check if it has occurred thrice in last 6 hours
c. If NO then pull all the alarms for this AlmCode with OccurTime >= Last 15 Minutes (If YES don't include & simply skip)
Upvotes: 0
Views: 129
Reputation: 136
All alarms, created in last 15 minutes (your query).
select distinct(AlmCode)
from TB_ALM
where AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978')
AND OccurTime >= date_sub(NOW(),interval 15 minute)
All alarms, HAS occurred thrice in any 15 minutes in last 6 hours (it will be excluded after)
select distinct t1.AlmCode
from TB_ALM t1
inner join TB_ALM t2 on t2.AlmCode = t1.AlmCode
and t2.OccurTime <= date_add(t1.OccurTime, interval 15 minute)
and t2.OccurTime > t1.OccurTime
inner join TB_ALM t3 on t3.AlmCode = t1.AlmCode
and t3.OccurTime <= date_add(t1.OccurTime, interval 15 minute)
and t3.OccurTime > t2.OccurTime
WHERE true
AND t1.OccurTime >= date_sub(now(), interval 6 hour)
AND t1.AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978')
So the final query is
select distinct(AlmCode)
from TB_ALM
where true
AND OccurTime >= date_sub(NOW(),interval 15 minute)
AND AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978')
AND AlmCode NOT IN (select distinct t1.AlmCode
from TB_ALM t1
inner join TB_ALM t2 on t2.AlmCode = t1.AlmCode
and t2.OccurTime <= date_add(t1.OccurTime, interval 15 minute)
and t2.OccurTime > t1.OccurTime
inner join TB_ALM t3 on t3.AlmCode = t1.AlmCode
and t3.OccurTime <= date_add(t1.OccurTime, interval 15 minute)
and t3.OccurTime > t2.OccurTime
WHERE true
AND t1.OccurTime >= date_sub(now(), interval 6 hour)
AND t1.AlmCode IN ('3236','4002','4008','4036','4050','4051','4102','4108','4136','4150','4151','4202','4208','4236','4250','4251','4801','4802','4836','4848','4850','4851','4902','4936','4950','4951','5002','5008','5036','5050','5051','5102','5108','5136','5150','5151','5202','5208','5236','5250','5251','5947','5950','5952','5975','5976','5977','5978')
)
Add index on AlmCode column, it will significantly decrease execution time
Upvotes: 1