调整 Informix 查询(Cisco 呼叫数据代理状态)
Posted
技术标签:
【中文标题】调整 Informix 查询(Cisco 呼叫数据代理状态)【英文标题】:Tweak for Informix Query (Cisco Call Data Agent State) 【发布时间】:2015-06-03 12:58:41 【问题描述】:看来我走到了死胡同。我正在从 Informix 数据库(思科呼叫中心数据)中提取数据,并尝试编写一个查询来显示每个代理状态的持续时间。我从中提取的表 (agentstatedetail) 中有 4 列:agentid、eventdatetime、eventtype 和 reasoncode。查询的目的是获取每个事件类型的持续时间。查询运行良好,但存在一个主要缺陷。当代理状态(对于相同的代理 ID)同时发生(下一个事件类型的事件日期时间相同)时,我的查询返回重复项,因为在我的子查询中我有 eventdatetime>asd1.eventdatetime。基本上我需要创建第二个 eventdatetime 列并将每一行向上移动 1,其中 agentid=agentid。我尝试使用 MIN 函数,但是正如我上面所说的,这个逻辑是有缺陷的,因为一些事件同时发生。我在下面粘贴了我的代码。我已经尝试创建一个索引表,但是因为我无法为我写入数据库,这不是一个选项。 另一种说法是,无论 agentid=agentid 的位置如何,我怎么说都取下一行?任何建议都会非常有帮助。谢谢!
照片链接: https://goo.gl/photos/sqM8GYdDZLrD3jAAA: 查询结果 https://goo.gl/photos/5E68jvwadjA5y5zZA:想要的结果 - 即 21 原因代码 = 午餐
表架构: (agentID:状态发生变化的agent的标识符,int,NOT NULL,Primary Key)
(eventDateTime: 代理状态改变的日期和时间。datetime year to fraction (3), NOT NULL, Primary Key)
(eventType: 触发代理状态变化的事件: smallint, NOT NULL, Primary Key)
(reasonCode: Null 如果没有配置原因码, smallint, NOT NULL, Primary Key)
select res.resourcename,
DATE(asd1.eventdatetime) as Date,
asd1.eventdatetime as starttime,
asd2.eventdatetime as endtime,
((asd2.eventdatetime-asd1.eventdatetime)::interval second(9) to second::char(10)::int) as duration,
asd1.reasoncode as reasoncodenum
from agentstatedetail asd1
join agentstatedetail asd2
on asd1.agentid=asd2.agentid
and asd2.eventdatetime = (select min(eventdatetime)
from agentstatedetail
where agentid = asd1.agentid
and eventdatetime>asd1.eventdatetime)
left join resource res on asd1.agentid=res.resourceid
where asd1.agentid=asd2.agentid
【问题讨论】:
不是答案,但为什么不将所有代码和描述存储在单独的表中?然后您可以加入并获取更改,现在所有查询都必须在代码更改时更新。 @jarlh 我没有写权限,不幸的是,这个数据库是由异地的其他人管理的。 【参考方案1】:所以给定的架构是:
create table agentstatedetail
(
agentid integer,
eventdatetime datetime year to fraction(3),
eventtype smallint,
reasoncode smallint,
primary key (agentid,eventdatetime,eventtype,reasoncode)
);
你只有下一个eventtype:
1 'Logged In'
2 'Not Ready'
3 'Ready'
4 'Reserved'
5 'Talking'
6 'Work'
7 'Logged Out'
您不需要报告eventtype 之间的转换,即使持续时间为 0 秒。
问题是当你有 0 秒时你会得到重复。
这些规则是否正确:
登录后,您始终处于未准备好; 未准备好之后,您始终处于准备好; 在 Ready 传递到 Not Ready 之后,您必须先Reserved。如果所有这些规则都正确,那么下面的测试用例应该可以工作:
CREATE TABLE agentstatedetail (
agentid INT,
eventtype INT,
eventdatetime DATETIME YEAR TO FRACTION
);
INSERT INTO agentstatedetail VALUES (1, 1, CURRENT - 1 UNITS HOUR);
INSERT INTO agentstatedetail VALUES (1, 2, CURRENT);
INSERT INTO agentstatedetail VALUES (1, 3, CURRENT);
INSERT INTO agentstatedetail VALUES (1, 4, CURRENT + 1 UNITS HOUR);
SELECT
t1.agentid AS agent_id,
t1.eventtype AS src_event_type,
t2.eventtype AS dst_event_type,
t1.eventdatetime AS start_time,
t2.eventdatetime AS stop_time,
(t2.eventdatetime - t1.eventdatetime ) AS durantion
FROM
agentstatedetail t1 JOIN agentstatedetail t2
ON t1.agentid = t2.agentid
AND t2.eventdatetime = (
SELECT MIN(eventdatetime )
FROM agentstatedetail
WHERE agentid = t1.agentid
AND eventdatetime >= t1.eventdatetime
AND NOT (
(t1.eventtype = eventtype )
OR (t1.eventtype = 1 AND eventtype = 3)
OR (t1.eventtype = 3 AND eventtype = 2)
OR (t1.eventtype = 2 AND eventtype = 4)
)
)
WHERE
NOT (
(t1.eventtype = t2.eventtype )
OR (t1.eventtype = 1 AND t2.eventtype = 3)
OR (t1.eventtype = 3 AND t2.eventtype = 2)
OR (t1.eventtype = 2 AND t2.eventtype = 4)
);
【讨论】:
@Ricardo 我已将表格的架构添加到问题中。我不太确定您所说的加入事件类型条件是什么意思。事件类型是相同的。该查询没有考虑同时发生的事件。所以它没有正确匹配一些事件。 @Ricardo - 我在我发布的问题上添加了链接,其中包含我想要的结果和结果。我希望这有助于理解这个问题。谢谢。 @Jason 对于这种情况,UNIQUE
必须足够。
@Ricardo 不幸的是,distinct/unique 在这种情况下不起作用,因为 Ready 和 Reserved 的时间完全相同,而实际上 Ready =0 其中 Reserved = X 的持续时间。我还能尝试什么?
@Jason 你说得对,我没有考虑持续时间。在这种情况下,如果您的结果集不是那么大,您可以在查询中添加一些逻辑或考虑使用临时表。要添加一些逻辑,如果您在未准备好之后总是有一个准备好,为您提供 0 持续时间,您可以添加到您的 where 子句 AND (asd1.eventtype!= 'NR' AND asd2.eventtype!='R')
。我们在持续时间大于 0 时使用 HAVING 子句。以上是关于调整 Informix 查询(Cisco 呼叫数据代理状态)的主要内容,如果未能解决你的问题,请参考以下文章