Sql查询更改 - 3表连接

时间:2016-06-22 11:47:00

标签: mysql sql

select 
  DISTINCT(destination_name),
  count(dst),TIME_FORMAT(SEC_TO_TIME(sum(duration)), '%H:%i:%s'),
  TIME_FORMAT(SEC_TO_TIME(sum(billsec)), '%H:%i:%s'),
  ROUND((sum(billsec)*cost) ,2),
  tarrif_plan.planname from tarrif_rate_domestic 
LEFT OUTER JOIN 
  tarrif_plan ON (tarrif_plan.planname = tarrif_rate_domestic.planname)  
LEFT OUTER JOIN cdr on (tarrif_plan.planname = tarrif_rate_domestic.planname) 
where cdr.dstchannel REGEXP tarrif_plan.trunkname and 
  cdr.dst REGEXP tarrif_rate_domestic.areacode and 
  disposition = 'ANSWERED' 
group by destination_name,tarrif_plan.planname;

输出:

  +------------------------+------------+-----------------------------------------------------+----------------------------------------------------+-------------------------------+----------------+
 | destination_name       | count(dst) | TIME_FORMAT(SEC_TO_TIME(sum(duration)), '%H:%i:%s') | TIME_FORMAT(SEC_TO_TIME(sum(billsec)), '%H:%i:%s') | ROUND((sum(billsec)*cost) ,2) | planname       |
 +------------------------+------------+-----------------------------------------------------+----------------------------------------------------+-------------------------------+----------------+
 | Mobile 2               |       3018 | 63:08:02                                            | 49:34:58                                           |                       3402.17 | Standard       |
 | Mobile 2               |         41 | 02:10:08                                            | 01:51:45                                           |                          0.00 | Other Provider |
 | On-Net                 |        455 | 16:30:37                                            | 15:19:22                                           |                        374.00 | Standard       |
 | On-Net                 |        712 | 50:45:15                                            | 49:51:03                                           |                          0.00 | Other Provider |
 | Special                |        143 | 11:51:49                                            | 11:43:07                                           |                        286.03 | Standard       |
 | Mobile                 |       3177 | 77:20:13                                            | 62:30:31                                           |                       4289.09 | Standard       |
 | Mobile                 |         80 | 03:28:29                                            | 02:52:08                                           |                          0.00 | Other Provider |
 +------------------------+------------+-----------------------------------------------------+----------------------------------------------------+-------------------------------+----------------+

但是我希望有一个额外的行来显示不匹配的值:可能是“未知”

我认为我需要使用CASE,但我无法找到需要添加到查询中的位置。

以下是3个表的一些数据:

Tarrif_plan:

 +----------+----------------+--------------+
 | uniqueid | planname       | trunkname    |
 +----------+----------------+--------------+
 |        1 | Standard       | IAX2/tmp     |
 |        2 | Other Provider | IAX2/myprov  |
 +----------+----------------+--------------+

Tarrif_rate_domestic:

 +----------+------------------------+--------------------------------------------------------------------------------------------+---------+----------------+
 | uniqueid | destination_name       | areacode     | cost    | planname       |
 +----------+------------------------+--------------------------------------------------------------------------------------------+---------+----------------+
 |        1 | Mobile 2               | 2[2]{9}      | 0.01906 | Standard       |
 |        2 | Mobile 2               | 2[2]{9}      | 0       | Other Provider |
 |        3 | Special                | 9[9]{9}      | 0.01906 | Standard       |
 |        4 | Special                | 9[9]{9}      | 0       | Other Provider |
 |        5 | Mobile                 | 1[1]{9}      | 0.00678 | Standard       |
 |        6 | Mobile                 | 1[1]{9}      | 0       | Other Provider |

CDR:

 +---------------------+------------+------------+-------------------+----------+---------+-------------+
 | calldate            | src        | dst        | dstchannel        | duration | billsec | disposition |
 +---------------------+------------+------------+-------------------+----------+---------+-------------+
 | 2016-06-20 03:28:23 | 100        | 2222222222 | IAX2/tmp-16938    |       28 |      21 | ANSWERED    |
 | 2016-06-20 04:39:11 | 7777777777 | 1111111111 |                   |       11 |      11 | ANSWERED    |
 | 2016-06-20 04:46:21 | 100        | 2222222222 | IAX2/tmp-22288    |       43 |      30 | ANSWERED    |
 | 2016-06-20 04:48:13 | 7777777777 | 1111111111 |                   |        9 |       9 | ANSWERED    |
 | 2016-06-20 04:53:15 | 100        | 4444444444 | IAX2/myprov-00d94 |        5 |       0 | NO ANSWER   |
 | 2016-06-20 05:01:03 | 100        | 9999999999 | IAX2/tmp-20367    |      914 |     893 | ANSWERED    |
 | 2016-06-20 05:12:47 | 100        | 200        | SIP/200-00000d98  |       16 |      13 | ANSWERED    |
 | 2016-06-20 05:15:38 | 100        | 9999999999 | IAX2/tmp-30597    |        1 |       0 | NO ANSWER   |
 | 2016-06-20 05:15:57 | 100        | 200        | SIP/200-00000d9c  |        3 |       0 | NO ANSWER   |
 | 2016-06-20 05:16:18 | 100        | 9999999999 | IAX2/tmp-22584    |       32 |       3 | ANSWERED    |
 | 2016-06-20 05:16:40 | 100        | 200        | SIP/200-00000da0  |        4 |       0 | NO ANSWER   |
 | 2016-06-20 05:17:58 | 100        | 1111111111 | IAX2/tmp-25515    |       23 |      14 | ANSWERED    |
 | 2016-06-20 05:19:39 | 100        | 200        | SIP/200-00000da4  |       29 |      24 | ANSWERED    |
 | 2016-06-20 05:20:45 | 8888888888 | 9999999999 | IAX2/myprov-00da7 |       81 |      81 | ANSWERED    |
 | 2016-06-20 05:21:13 | 100        | 4444444444 | IAX2/tmp-29717    |      339 |     311 | ANSWERED    |
 | 2016-06-20 05:21:25 | 100        | 2222222222 | IAX2/tmp-17460    |       40 |       3 | ANSWERED    |
 | 2016-06-20 05:21:45 | 100        | 200        | SIP/200-00000daa  |       21 |       0 | NO ANSWER   |
 | 2016-06-20 05:23:16 | 100        | 200        | SIP/200-00000dae  |       54 |      51 | ANSWERED    |
 | 2016-06-20 05:24:30 | 100        | 2222222222 | IAX2/tmp-19105    |       19 |       3 | ANSWERED    |
 | 2016-06-20 05:26:10 | 100        | 1111111111 | IAX2/tmp-24135    |       54 |      23 | ANSWERED    |
 +---------------------+------------+------------+-------------------+----------+---------+-------------+

所以回顾一下:

  1. 使用tarrif_plan仅查找CDR中cdr.dstchannel与tarrif_plan.trunkname(REGEXP)匹配的记录
  2. 如果cdr.dst与tarrif_rate_domestic.areacode(REGEXP)匹配,则使用Tarrif_plan获取目标名称 注意:如果未找到匹配项,则显示为“未知”exp:4444444444

3 个答案:

答案 0 :(得分:0)

您可以在select中添加CASE,我在下面尝试过

select 
  CASE
     WHEN destination_name IS NULL THEN 'Unknown'
     ELSE destination_name
     END as destination_name,
  count(dst),TIME_FORMAT(SEC_TO_TIME(sum(duration)), '%H:%i:%s'),
  TIME_FORMAT(SEC_TO_TIME(sum(billsec)), '%H:%i:%s'),
  ROUND((sum(billsec)*cost) ,2),
  tarrif_plan.planname from tarrif_rate_domestic 
LEFT OUTER JOIN 
  tarrif_plan ON (tarrif_plan.planname = tarrif_rate_domestic.planname)  
LEFT OUTER JOIN cdr on (tarrif_plan.planname = tarrif_rate_domestic.planname) 
where cdr.dstchannel REGEXP tarrif_plan.trunkname and 
  cdr.dst REGEXP tarrif_rate_domestic.areacode and 
  disposition = 'ANSWERED' 
group by destination_name,tarrif_plan.planname;

虽然我不确定您更喜欢哪个列,但请根据需要调整查询大小。

解决方案参考 - Joining two tables when there is a not matching record exist

答案 1 :(得分:0)

我怀疑我找到了解决方案:

select 
  count(dst),duration,TIME_FORMAT(SEC_TO_TIME(billsec), '%H:%i:%s') as talktime,
  ROUND((billsec*cost) ,2), 
  CASE WHEN destination_name IS NULL 
    THEN 'Unknown' ELSE destination_name END as Destname, tarrif_plan.planname 
from cdr 
LEFT OUTER JOIN tarrif_rate_domestic ON (cdr.dst REGEXP tarrif_rate_domestic.areacode) 
LEFT JOIN tarrif_plan ON (tarrif_plan.planname = tarrif_rate_domestic.planname) 
where 
  (cdr.dstchannel REGEXP tarrif_plan.trunkname or tarrif_plan.trunkname is null) and 
  disposition = 'ANSWERED' 
group by destname,tarrif_rate_domestic.planname;

需要尝试找出不同之处。

答案 2 :(得分:0)

以下我可以确认完全按预期工作:

SELECT 
   count(pf.dst), 
   TIME_FORMAT(SEC_TO_TIME(sum(pf.duration)), '%H:%i:%s') as totaltime, 
   TIME_FORMAT(SEC_TO_TIME(sum(pf.billsec)), '%H:%i:%s') as talktime, 
   ROUND((sum(pf.billsec*f.cost)), 2), 
   f.planname, 
   f.destination_name 
FROM cdr AS pf 
  LEFT JOIN tarrif_plan AS p ON pf.dstchannel REGEXP p.trunkname 
  LEFT JOIN tarrif_rate_domestic AS f ON pf.dst REGEXP f.areacode 
WHERE 
   trunkname is not null and 
   (p.planname = f.planname or f.planname is null) 
GROUP BY f.destination_name,f.planname;