MySQL中如何根据同uniqueid其他行值设置Asterisk CDR的isToDiscard字段
方案可行性确认
添加isToDiscard字段的方案完全可行,这种方式能把判断逻辑提前固化到数据中,避免每次查询都做关联计算,对桌面程序的查询性能更友好,数据量越大优势越明显。
具体实现方法
1. 新增字段
先给CDR表添加布尔类型的isToDiscard字段,默认值设为FALSE:
ALTER TABLE cdr ADD COLUMN isToDiscard BOOLEAN DEFAULT FALSE;
2. 用触发器自动标记新数据
创建触发器,每次插入新CDR记录后,自动检查同uniqueid下是否存在disposition为ANSWER的记录,若存在则把该uniqueid下所有NO ANSWER的记录标记为isToDiscard=TRUE。以下是MySQL环境的示例代码:
DELIMITER // CREATE TRIGGER update_isToDiscard_after_insert AFTER INSERT ON cdr FOR EACH ROW BEGIN DECLARE has_answer INT; -- 统计当前uniqueid下接听记录的数量 SELECT COUNT(*) INTO has_answer FROM cdr WHERE uniqueid = NEW.uniqueid AND disposition = 'ANSWER'; -- 存在接听记录时,标记该uniqueid下所有未接记录为待丢弃 IF has_answer > 0 THEN UPDATE cdr SET isToDiscard = TRUE WHERE uniqueid = NEW.uniqueid AND disposition = 'NO ANSWER'; END IF; END // DELIMITER ;
如果你的数据库是PostgreSQL等,语法会略有不同,但核心逻辑一致:插入后检查同uniqueid的接听状态,批量更新标记。
3. 批量更新历史数据
对于已经存在的旧数据,需要一次性完成标记:
-- 先筛选出所有有接听记录的uniqueid,再标记对应未接记录 WITH answer_uniqueids AS ( SELECT DISTINCT uniqueid FROM cdr WHERE disposition = 'ANSWER' ) UPDATE cdr SET isToDiscard = TRUE WHERE disposition = 'NO ANSWER' AND uniqueid IN (SELECT uniqueid FROM answer_uniqueids);
如果数据库不支持WITH子句(如MySQL 5.x),可以改用子查询:
UPDATE cdr SET isToDiscard = TRUE WHERE disposition = 'NO ANSWER' AND uniqueid IN ( SELECT DISTINCT uniqueid FROM cdr WHERE disposition = 'ANSWER' );
4. 查询使用示例
查询指定分机(比如200)的有效呼叫记录时,直接过滤即可:
SELECT * FROM cdr WHERE extension = '200' AND (disposition != 'NO ANSWER' OR isToDiscard = FALSE);
这条SQL会返回:该分机接听的记录,以及未接听但同uniqueid下所有分机都未接听的记录,完全符合你的需求。
内容的提问来源于stack exchange,提问作者dotthor
相关产品推荐
相关产品推荐

