MYSQL查询帮助:结果不是100%准确

时间:2015-06-16 14:00:07

标签: mysql

我有一个包含呼叫详细记录的mysql数据库。在这个特定的查询中,我想搜索所有呼叫,原因是呼叫被断开,并返回断开原因的列表以及每个呼叫发生的次数。

示例结果集看起来像这样:

 causeCode | count
           |
 0         | 380
 16        | 289
 47        | 2

一条记录代表一次通话。每个记录包含两个字段,其中包含断开连接原因origCause_value,它指定发起方断开呼叫的断开原因,destCause_value指定被叫方断开呼叫的断开原因。< / p>

我使用的查询在大多数情况下工作得很好,但问题是这个。起初我认为每条记录在origCause_valuedestCause_value中只有1个值,具体取决于哪一方断开了呼叫。我发现虽然大部分时间都是如此,但有些记录会填写两个字段。这会导致我的计数失败,因此它不是100%准确。

例如:

 Above shows that cause code 47 was used 2 times.  
 Technically this is correct because in one record it is in both the
 origCause_value and destCause_value field.  


However the results i'd like to see returned would be 1.  
To indicate the  number of calls that were terminated with cause code 47

以下是我正在使用的查询:

 SELECT c.causeCode, sum(count) as count
 FROM ((SELECT origCause_value as causeCode, COUNT(origCause_value) AS count
   FROM CDR
   GROUP BY causeCode
  ) UNION ALL
  (SELECT  destCause_value as causeCode, COUNT(destCause_value) AS count
   FROM CDR
   GROUP BY causeCode
  )
 ) c
 GROUP BY c.causeCode ORDER BY count DESC

我正在寻求帮助,看看是否有一种方法可以将其过滤掉以获得所需的结果。

示例表:

 id  | CallingPartyNumber | finalCalledPartyNumber | origCause_value | destCause_value
 1              5551212             7771212             16              0
 2              5551212             7771212             0               16
 3              7771212             5551212             47              47
 4              7771212             5551212             16              0
 5              5551212             777121              16              0 

提前致谢。

1 个答案:

答案 0 :(得分:1)

47(没有资源)是一个奇怪的原因代码。发生这种情况时,两端可以同时断开连接。

大多数调用只有一端断开导致代码。您的CDR表显示从最后开始的零原因,不会导致断开连接。

你显然希望拥有与CDR中有行相同数量的断开连接原因,否则你会感到困惑。

   SELECT COUNT(*) cause_count, 
          CASE WHEN origCause_value <> 0 
               THEN origCause_value
               ELSE destCause_value
                END cause_value
     FROM CDR
    GROUP BY CASE WHEN origCause_value <> 0 
                  THEN origCause_value
                  ELSE destCause_value
                   END 
    ORDER BY COUNT(*) DESC

以下是此查询的演示。 http://sqlfiddle.com/#!9/a8527/1/0

CASE语句从每条记录中获取非零原因代码。

您也可以使用GREATEST(origCause_value, destCause_value),但它可能不太健壮。

(我编辑了这个答案;我之前使用的COALESCE()假设未设置的原因代码是NULL,而不是零。

修改

您的新样本(http://sqlfiddle.com/#!9/9f3ba/1)作为其第二条记录:

 (2,5551212,7771212,393216,16),

这是什么意思?这应该算作“16” - 来自接收端的正常呼叫终止吗?或者393216值(0x60000)是否具有某种特殊含义?

获得正确的计数可能意味着您需要了解这些原因代码对的含义。我给你的查询会将CDR计为393216,因为它会获取第一个数字,而不是第二个数字。