使用MySQL从费率表计算通话费用

时间:2013-09-03 23:52:54

标签: mysql sql cdr

我正在尝试比较两家电话提供商之间的通话费率。我有两张表,如下:

CREATE TABLE 18185_rates (
  calldate DATE,
  calltime TIME,
  calledno VARCHAR(20),
  duration INTEGER(8),
  callcost FLOAT(5 , 3 )
);

CREATE TABLE int_rates (
  dialcode VARCHAR(20),
  description VARCHAR(20),
  callcost FLOAT(5 , 3 )
);

18185_rates包含来自电话系统的呼叫数据记录,一些示例值如下:

calldate,calltime,calledno,duration,callcost
2013-07-30,11:21:38,35342245738,10,0.050
2013-07-30,16:19:25,353872565822,37,0.130
2013-08-02,08:31:12,65975636187,1344,0.270
2013-08-05,11:03:53,919311195965,2356,1.640

表int_rates包含来自其他提供商的呼叫的资费数据,格式如下:

dialcode,description,callcost
1,USA,0.012
1204,Canada,0.008
1204131,Canada,0.018
1226,Canada,0.008
1226131,Canada,0.018
1242,Bahamas,0.137
1242357,Bahamas Mobile,0.251
1242359,Bahamas Mobile,0.251

我正在尝试进行比较,以便我可以看到18185_rates中的调用与其他提供商相比会花多少钱。我无法弄清楚如何根据int_rates中的可变长度拨号代码加入这两个表。

在下面的@Gordon Linoff的帮助下,我想出了以下代码:

SELECT 
    r.*,
    (SELECT permin
     FROM int_rates ir1
     WHERE r.calledno LIKE CONCAT(ir1.dialcode, '%')
     ORDER BY dialcode DESC
     LIMIT 1) AS newcostpermin
FROM
  18185_rates r;

1 个答案:

答案 0 :(得分:0)

我假设您希望将每个电话号码与具有最长前缀的费用相匹配。这是一种方法:

select ir.*,
       (select callcost
        from int_rates ir
        where r.calledno like concat(ir.dialcode, '%')
        order by length(ir.dialcode) desc
        limit 1
       ) as TheirCost
from 18185_rates r;

这是使用相关子查询来查找与调用开始匹配的最长拨号代码。如果没有匹配,这将是NULL。此外,这将无效并且无法使用索引。

编辑:

有不同的方法来解决这个问题。最简单的只是复制子查询:

select ir.*,
       (select callcost
        from int_rates ir
        where r.calledno like concat(ir.dialcode, '%')
        order by length(ir.dialcode) desc
        limit 1
       ) as TheirCost,
       (select description
        from int_rates ir
        where r.calledno like concat(ir.dialcode, '%')
        order by length(ir.dialcode) desc
        limit 1
       ) as TheirDescription
from 18185_rates r;

实际上,我会在第一个子查询中拉出一个主键,然后再加入表中,从该表中获取我想要的任何字段。但是,您没有指定表格布局,如果第一个查询具有合理的性能,那么执行两次也应该没问题。