如何统计 Informix SQL 的差异?
How to count the difference in Informix SQL?
我正在计算呼叫中心的评分呼叫数和平均评分:
select cr.queue, ROUND(AVG(TO_NUMBER(cd.datavalue)),2) as average, count(*) as count
from callrecord cr
left join calldata cd on cd.callid=cr.callid
where cd.datakey="qrate1"
group by queue
|queue |average |count |
+---------+----------+--------+
|sales |3.92 |12 |
|service |3.75 |4 |
(12 个额定销售电话和 4 个额定服务电话)。
我还可以计算总调用次数(已评级和未评级):
select cr.queue, 0 as average, count(*) as count
from callrecord cr
group by queue
|queue |average |count |
+---------+----------+--------+
|sales |0 |21 |
|service |0 |4 |
(总共 21 个销售电话和 4 个服务电话)。
但我只想计算未评级的电话。 SQL 请求:
select cr.queue, 0 as average, count(*) as count
from callrecord cr
left join calldata cd on cd.callid=cr.callid
where cd.datakey!="qrate1"
group by queue
运行缓慢并产生不正确的结果,例如
|queue |average |count |
+---------+----------+--------+
|sales |0 |69 |
|service |0 |16 |
(69 个未评级的销售电话和 16 个未评级的服务电话 - 不正确)。
因此未评级的计数 = 总计 - 已评级,我无法构建一个 SQL 我可以得到这个结果的地方。
期望的结果应该是:
|queue |average |count |
+---------+----------+--------+
|sales |0 |9 |
|service |0 |0 |
(21-12=9 个未评级的销售电话和 4-4=0 个未评级的服务电话)。
CALLDATA 示例table:
|callid |datakey |datavalue |
+---------+----------+-----------+
|181 |ANI |1234567890 |
|181 |DNIT |2345678901 |
|181 |IVR_CHOICE|SALES |
|182 |ANI |1234567890 |
|182 |DNIT |2345678901 |
|182 |QRATE1 |1 |
|183 |ANI |1234567890 |
|183 |DNIT |2345678901 |
|183 |LANG |ENGLISH |
最后我为 dbfiddle.uk 准备了一个脚本来玩这个场景:
select *
into calldata
from (values ('181','ANI','1234567890')
, ('181','DNIT','2345678901')
, ('181','IVR_CHOICE','SALES')
, ('182','ANI','1234567890')
, ('182','DNIT','2345678901')
, ('182','QRATE1','1')
, ('183','ANI','1234567890')
, ('183','DNIT','2345678901')
, ('183','LANG','ENGLISH') ) z(callid,datakey,datavalue);
select *
into callrecord
from (values ('181','SALES')
, ('182','SALES' )
, ('183','SALES' ) ) z(callid,queue);
GO
12 rows affected
select queue, count(*) as total
from callrecord
group by queue
GO
queue | total
:---- | ----:
SALES | 3
select cr.queue, count(*) as rated
from callrecord cr
left join calldata cd on cr.callid=cd.callid
where cd.datakey='QRATE1'
group by queue
GO
queue | rated
:---- | ----:
SALES | 1
select cr.queue, count(*) as unrated
from callrecord cr
left join calldata cd on cr.callid=cd.callid
where cd.datakey<>'QRATE1'
group by queue
GO
queue | unrated
:---- | ------:
SALES | 8
select cr.queue, SUM(CASE WHEN cd.datakey='QRATE1' THEN 0 ELSE 1 END) as unrated
from callrecord cr
left join calldata cd on cr.callid=cd.callid
group by queue
GO
queue | unrated
:---- | ------:
SALES | 8
db<>fiddle here
由于不想统计child table, calldata,匹配的记录只统计callrecord层记录,考虑将 EXISTS
子句(或 IN
)与相关子查询一起使用:
-- EXISTS
select cr.queue, count(*) as rated
from callrecord cr
where exists (
select 1 from calldata cd
where cd.callid = cr.callid
and cd.datakey = 'QRATE1'
)
group by queue
-- NOT EXISTS
select cr.queue, count(*) as rated
from callrecord cr
where not exists (
select 1 from calldata cd
where cd.callid = cr.callid
and cd.datakey = 'QRATE1'
)
group by queue
我正在计算呼叫中心的评分呼叫数和平均评分:
select cr.queue, ROUND(AVG(TO_NUMBER(cd.datavalue)),2) as average, count(*) as count
from callrecord cr
left join calldata cd on cd.callid=cr.callid
where cd.datakey="qrate1"
group by queue
|queue |average |count |
+---------+----------+--------+
|sales |3.92 |12 |
|service |3.75 |4 |
(12 个额定销售电话和 4 个额定服务电话)。
我还可以计算总调用次数(已评级和未评级):
select cr.queue, 0 as average, count(*) as count
from callrecord cr
group by queue
|queue |average |count |
+---------+----------+--------+
|sales |0 |21 |
|service |0 |4 |
(总共 21 个销售电话和 4 个服务电话)。
但我只想计算未评级的电话。 SQL 请求:
select cr.queue, 0 as average, count(*) as count
from callrecord cr
left join calldata cd on cd.callid=cr.callid
where cd.datakey!="qrate1"
group by queue
运行缓慢并产生不正确的结果,例如
|queue |average |count |
+---------+----------+--------+
|sales |0 |69 |
|service |0 |16 |
(69 个未评级的销售电话和 16 个未评级的服务电话 - 不正确)。
因此未评级的计数 = 总计 - 已评级,我无法构建一个 SQL 我可以得到这个结果的地方。
期望的结果应该是:
|queue |average |count |
+---------+----------+--------+
|sales |0 |9 |
|service |0 |0 |
(21-12=9 个未评级的销售电话和 4-4=0 个未评级的服务电话)。
CALLDATA 示例table:
|callid |datakey |datavalue |
+---------+----------+-----------+
|181 |ANI |1234567890 |
|181 |DNIT |2345678901 |
|181 |IVR_CHOICE|SALES |
|182 |ANI |1234567890 |
|182 |DNIT |2345678901 |
|182 |QRATE1 |1 |
|183 |ANI |1234567890 |
|183 |DNIT |2345678901 |
|183 |LANG |ENGLISH |
最后我为 dbfiddle.uk 准备了一个脚本来玩这个场景:
select * into calldata from (values ('181','ANI','1234567890') , ('181','DNIT','2345678901') , ('181','IVR_CHOICE','SALES') , ('182','ANI','1234567890') , ('182','DNIT','2345678901') , ('182','QRATE1','1') , ('183','ANI','1234567890') , ('183','DNIT','2345678901') , ('183','LANG','ENGLISH') ) z(callid,datakey,datavalue); select * into callrecord from (values ('181','SALES') , ('182','SALES' ) , ('183','SALES' ) ) z(callid,queue); GO
12 rows affected
select queue, count(*) as total from callrecord group by queue GO
queue | total :---- | ----: SALES | 3
select cr.queue, count(*) as rated from callrecord cr left join calldata cd on cr.callid=cd.callid where cd.datakey='QRATE1' group by queue GO
queue | rated :---- | ----: SALES | 1
select cr.queue, count(*) as unrated from callrecord cr left join calldata cd on cr.callid=cd.callid where cd.datakey<>'QRATE1' group by queue GO
queue | unrated :---- | ------: SALES | 8
select cr.queue, SUM(CASE WHEN cd.datakey='QRATE1' THEN 0 ELSE 1 END) as unrated from callrecord cr left join calldata cd on cr.callid=cd.callid group by queue GO
queue | unrated :---- | ------: SALES | 8
db<>fiddle here
由于不想统计child table, calldata,匹配的记录只统计callrecord层记录,考虑将 EXISTS
子句(或 IN
)与相关子查询一起使用:
-- EXISTS
select cr.queue, count(*) as rated
from callrecord cr
where exists (
select 1 from calldata cd
where cd.callid = cr.callid
and cd.datakey = 'QRATE1'
)
group by queue
-- NOT EXISTS
select cr.queue, count(*) as rated
from callrecord cr
where not exists (
select 1 from calldata cd
where cd.callid = cr.callid
and cd.datakey = 'QRATE1'
)
group by queue