创建查询以获取未完成呼叫的计数
Create query to get count of uncompleted calls
有tablewaiter_log为
+---------+----------------+--------------+--------------+
| call_id | queue_num_curr | ast_num_curr | proceed_wait |
+---------+----------------+--------------+--------------+
| f27de4f | 9010 | 2 | 1 |
| f27de4f | 9002 | 5 | 1 |
| f27de4f | 9003 | 1 | 0 |
| asdf231 | 9010 | 2 | 1 |
| asdf231 | 9002 | 5 | 1 |
| rete125 | 9010 | 2 | 1 |
| rete125 | 9009 | 5 | 1 |
| a7rf5gs | 9003 | 2 | 1 |
| a7rf5gs | 9006 | 5 | 1 |
| a7rf5gs | 9009 | 1 | 0 |
| qawe234 | 9003 | 2 | 1 |
| qawe234 | 9008 | 5 | 1 |
| qawe234 | 9004 | 1 | 0 |
| 49c43ad | 9004 | 2 | 1 |
| 49c43ad | 9007 | 5 | 1 |
+---------+----------------+--------------+--------------+
通话 ID 为 'f27de4f' 的通话开始于 9010 年,结束于 9003 年,因为对于通话 ID='f27de4f'
有一条 proceed_wait = 0 的记录
call-id 'asdf231' 的呼叫从 9010 开始,仍在 9002 继续并且尚未完成,因为没有 call-id='asdf231' 的 proceed_wait = 0 的记录
同样,对于呼叫 ID 'rete125' 的呼叫,没有 proceed_wait = 0 的记录,并且此呼叫也未完成。
所以,对于队列 9010 查询结果应该是 2(未完成呼叫的计数)
对于 9003,结果应为 0 ,因为对 9003('a7rf5gs' 和 'qawe234')的所有调用都已完成。
对于 9004,结果应为 1,因为对于呼叫 ID 为“49c43ad”的呼叫,没有 proceed_wait = 0 的记录。
如何创建查询以获取未完成呼叫的计数:
queue_num count
9010 2
9004 1
更新:
在这里我更新了我的问题
如果你是运行 MySQL 8.0,你可以用window函数来做到这一点:
select
min_queue_num_curr queue_num_curr,
count(*) cnt
from (
select
proceed_wait ,
row_number() over(partition by call_id order by queue_num_curr desc) rn,
min(queue_num_curr) over(partition by call_id) min_queue_num_curr
from mytable
) t
where rn = 1 and proceed_wait = 1
group by min_queue_num_curr
子查询检索每个call_id
的起始queue_num_curr
并对每个调用的记录进行排序。外部查询过滤最后一个记录 par 调用和未完成的调用,并通过开始 queue_num_curr
.
进行聚合
queue_num_curr | cnt
-------------: | --:
9001 | 2
9003 | 1
9004 | 1
注意:调用 a7rf5gs
开始于 queue_num_curr = 9003
并在 queue_num_curr = 9009
上进行了 proceed_wait = 1
,因此它也应该被视为未完成。
在早期版本中,您可以自行加入 table 以获取每个调用的开始 queue_num_cur
,并使用相关子查询来过滤每个调用 ID 的最后一条记录。然后您可以过滤未完成的记录并通过开始 queue_num_cur
:
进行聚合
select tmin.queue_num_curr, count(*)
from mytable t
inner join (
select call_id, min(queue_num_curr) queue_num_curr from mytable group by call_id
) tmin on tmin.call_id = t.call_id
where
t.queue_num_curr = (
select max(t1.queue_num_curr) from mytable t1 where t1.call_id = t.call_id
)
and t.proceed_wait = 1
group by tmin.queue_num_curr
order by tmin.queue_num_curr
如果我对逻辑的理解正确(对此我不确定),您可以 GROUP BY
队列和 count()
没有记录的不同呼叫 ID proceed_wait = 0
存在,可以通过相关子查询查询。
SELECT wl1.queue_num_curr,
count(DISTINCT
(SELECT wl1.call_id
FROM dual
WHERE NOT EXISTS (SELECT *
FROM waiter_log wl2
WHERE wl2.call_id = wl1.call_id
AND wl2.proceed_wait = 0))) count
FROM waiter_log wl1
GROUP BY wl1.queue_num_curr;
如果 (call_id, queue_num_curr)
是唯一的,即没有呼叫在队列中出现超过一次,可以简化为只取 NOT EXISTS
的 sum()
(因为布尔值表达式在数字上下文中映射到 0(表示假)或 1(表示真)。
SELECT wl1.queue_num_curr,
sum(NOT EXISTS (SELECT *
FROM waiter_log wl2
WHERE wl2.call_id = wl1.call_id
AND wl2.proceed_wait = 0)) count
FROM waiter_log wl1
GROUP BY wl1.queue_num_curr;
这是另一种无需相关子查询或 window 函数即可工作的方法:
对于每一行 w1
,尝试找到具有相同 call_id 和 0 的另一行 w2
,表示调用已完成。使用 LEFT OUTER JOIN,我们可以测试给定 call_id.
不存在 w2
行的情况
然后使用相同的 call_id 和较小的 ast_num_curr 值对假设的行 w3
进行另一个连接。同样,使用外连接,我们可以检查不存在这样的行。这意味着 w1
必须具有最小的 ast num 值 call_id。
SELECT w1.call_id, w1.queue_num_curr
FROM waiter_log AS w1
LEFT OUTER JOIN waiter_log AS w2
ON w1.call_id = w2.call_id AND w2.proceed_wait = 0
LEFT OUTER JOIN waiter_log AS w3
ON w1.call_id = w3.call_id AND w1.ast_num_curr > w3.ast_num_curr
WHERE w2.call_id IS NULL AND w3.call_id IS NULL;
输出:
+---------+----------------+
| call_id | queue_num_curr |
+---------+----------------+
| 49c43ad | 9004 |
| asdf231 | 9010 |
| rete125 | 9010 |
+---------+----------------+
要获取每个 queue_num_curr 的计数,请将上面的查询包装在派生的 table 子查询中,并在外部查询中进行计数:
SELECT queue_num_curr, COUNT(*) AS count
FROM (
SELECT w1.call_id, w1.queue_num_curr
FROM waiter_log AS w1
LEFT OUTER JOIN waiter_log AS w2
ON w1.call_id = w2.call_id AND w2.proceed_wait = 0
LEFT OUTER JOIN waiter_log AS w3
ON w1.call_id = w3.call_id AND w1.ast_num_curr > w3.ast_num_curr
WHERE w2.call_id IS NULL AND w3.call_id IS NULL
) AS t
GROUP BY queue_num_curr;
输出:
+----------------+-------+
| queue_num_curr | count |
+----------------+-------+
| 9004 | 1 |
| 9010 | 2 |
+----------------+-------+
有tablewaiter_log为
+---------+----------------+--------------+--------------+
| call_id | queue_num_curr | ast_num_curr | proceed_wait |
+---------+----------------+--------------+--------------+
| f27de4f | 9010 | 2 | 1 |
| f27de4f | 9002 | 5 | 1 |
| f27de4f | 9003 | 1 | 0 |
| asdf231 | 9010 | 2 | 1 |
| asdf231 | 9002 | 5 | 1 |
| rete125 | 9010 | 2 | 1 |
| rete125 | 9009 | 5 | 1 |
| a7rf5gs | 9003 | 2 | 1 |
| a7rf5gs | 9006 | 5 | 1 |
| a7rf5gs | 9009 | 1 | 0 |
| qawe234 | 9003 | 2 | 1 |
| qawe234 | 9008 | 5 | 1 |
| qawe234 | 9004 | 1 | 0 |
| 49c43ad | 9004 | 2 | 1 |
| 49c43ad | 9007 | 5 | 1 |
+---------+----------------+--------------+--------------+
通话 ID 为 'f27de4f' 的通话开始于 9010 年,结束于 9003 年,因为对于通话 ID='f27de4f'
有一条 proceed_wait = 0 的记录
call-id 'asdf231' 的呼叫从 9010 开始,仍在 9002 继续并且尚未完成,因为没有 call-id='asdf231' 的 proceed_wait = 0 的记录
同样,对于呼叫 ID 'rete125' 的呼叫,没有 proceed_wait = 0 的记录,并且此呼叫也未完成。
所以,对于队列 9010 查询结果应该是 2(未完成呼叫的计数)
对于 9003,结果应为 0 ,因为对 9003('a7rf5gs' 和 'qawe234')的所有调用都已完成。
对于 9004,结果应为 1,因为对于呼叫 ID 为“49c43ad”的呼叫,没有 proceed_wait = 0 的记录。
如何创建查询以获取未完成呼叫的计数:
queue_num count
9010 2
9004 1
更新:
在这里我更新了我的问题
如果你是运行 MySQL 8.0,你可以用window函数来做到这一点:
select
min_queue_num_curr queue_num_curr,
count(*) cnt
from (
select
proceed_wait ,
row_number() over(partition by call_id order by queue_num_curr desc) rn,
min(queue_num_curr) over(partition by call_id) min_queue_num_curr
from mytable
) t
where rn = 1 and proceed_wait = 1
group by min_queue_num_curr
子查询检索每个call_id
的起始queue_num_curr
并对每个调用的记录进行排序。外部查询过滤最后一个记录 par 调用和未完成的调用,并通过开始 queue_num_curr
.
queue_num_curr | cnt -------------: | --: 9001 | 2 9003 | 1 9004 | 1
注意:调用 a7rf5gs
开始于 queue_num_curr = 9003
并在 queue_num_curr = 9009
上进行了 proceed_wait = 1
,因此它也应该被视为未完成。
在早期版本中,您可以自行加入 table 以获取每个调用的开始 queue_num_cur
,并使用相关子查询来过滤每个调用 ID 的最后一条记录。然后您可以过滤未完成的记录并通过开始 queue_num_cur
:
select tmin.queue_num_curr, count(*)
from mytable t
inner join (
select call_id, min(queue_num_curr) queue_num_curr from mytable group by call_id
) tmin on tmin.call_id = t.call_id
where
t.queue_num_curr = (
select max(t1.queue_num_curr) from mytable t1 where t1.call_id = t.call_id
)
and t.proceed_wait = 1
group by tmin.queue_num_curr
order by tmin.queue_num_curr
如果我对逻辑的理解正确(对此我不确定),您可以 GROUP BY
队列和 count()
没有记录的不同呼叫 ID proceed_wait = 0
存在,可以通过相关子查询查询。
SELECT wl1.queue_num_curr,
count(DISTINCT
(SELECT wl1.call_id
FROM dual
WHERE NOT EXISTS (SELECT *
FROM waiter_log wl2
WHERE wl2.call_id = wl1.call_id
AND wl2.proceed_wait = 0))) count
FROM waiter_log wl1
GROUP BY wl1.queue_num_curr;
如果 (call_id, queue_num_curr)
是唯一的,即没有呼叫在队列中出现超过一次,可以简化为只取 NOT EXISTS
的 sum()
(因为布尔值表达式在数字上下文中映射到 0(表示假)或 1(表示真)。
SELECT wl1.queue_num_curr,
sum(NOT EXISTS (SELECT *
FROM waiter_log wl2
WHERE wl2.call_id = wl1.call_id
AND wl2.proceed_wait = 0)) count
FROM waiter_log wl1
GROUP BY wl1.queue_num_curr;
这是另一种无需相关子查询或 window 函数即可工作的方法:
对于每一行 w1
,尝试找到具有相同 call_id 和 0 的另一行 w2
,表示调用已完成。使用 LEFT OUTER JOIN,我们可以测试给定 call_id.
w2
行的情况
然后使用相同的 call_id 和较小的 ast_num_curr 值对假设的行 w3
进行另一个连接。同样,使用外连接,我们可以检查不存在这样的行。这意味着 w1
必须具有最小的 ast num 值 call_id。
SELECT w1.call_id, w1.queue_num_curr
FROM waiter_log AS w1
LEFT OUTER JOIN waiter_log AS w2
ON w1.call_id = w2.call_id AND w2.proceed_wait = 0
LEFT OUTER JOIN waiter_log AS w3
ON w1.call_id = w3.call_id AND w1.ast_num_curr > w3.ast_num_curr
WHERE w2.call_id IS NULL AND w3.call_id IS NULL;
输出:
+---------+----------------+
| call_id | queue_num_curr |
+---------+----------------+
| 49c43ad | 9004 |
| asdf231 | 9010 |
| rete125 | 9010 |
+---------+----------------+
要获取每个 queue_num_curr 的计数,请将上面的查询包装在派生的 table 子查询中,并在外部查询中进行计数:
SELECT queue_num_curr, COUNT(*) AS count
FROM (
SELECT w1.call_id, w1.queue_num_curr
FROM waiter_log AS w1
LEFT OUTER JOIN waiter_log AS w2
ON w1.call_id = w2.call_id AND w2.proceed_wait = 0
LEFT OUTER JOIN waiter_log AS w3
ON w1.call_id = w3.call_id AND w1.ast_num_curr > w3.ast_num_curr
WHERE w2.call_id IS NULL AND w3.call_id IS NULL
) AS t
GROUP BY queue_num_curr;
输出:
+----------------+-------+
| queue_num_curr | count |
+----------------+-------+
| 9004 | 1 |
| 9010 | 2 |
+----------------+-------+