MYSQL查询与第二个表最接近的匹配

时间:2013-09-28 20:06:04

标签: php mysql sql

您好我有2个表格结构如下

cdr

src  | bill sec   | clean_dst
------------------------------
100  | 10        | 18006927753
100  | 22        | 18006927753
100  | 9         | 441138973356


dialing_codes

id    | dial_code  | tele2id
-----------------------------
1     | 1         | 1422
2     | 1800      | 1433
3     | 441       | 1024
4     | 4413      | 1086

我需要在dial_code中针对clean_dst获取最接近匹配的tele2id到目前为止,我的最大努力是

$query = "SELECT tele2id, dial_code FROM dialing_codes ORDER by dial_code DESC";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
while($row = $result->fetch_assoc()) {
$tele2id = $row['tele2id'];
$dialcode = $row['dial_code'];  
$query2 = "SELECT clean_dst FROM cdr WHERE clean_dst LIKE '".$dialcode."%'";
$result2 = $mysqli->query($query2) or die($mysqli->error.__LINE__);
while($row2 = $result2->fetch_assoc()) {

我认为这是有效的,但经过仔细检查,如果重复clean_dst,它只会在第一次返回正确的结果

例如

clean_dst    dial_code     tele2id
18006927753  1800          1433
18006927753  1             1422

我做错了什么?感谢

如果有帮助我需要最匹配数字的结果?

2 个答案:

答案 0 :(得分:0)

请尝试此查询:

select dial_code, clean_dst from cdr c, dialing_codes d where c.clean_dst
  like concat(d.dial_code, '%');

您不需要在php中编写所有逻辑代码。 MySQL为您提供了在SQL中本机执行的功能和比较,这更简单,更简洁。

希望这有帮助。

答案 1 :(得分:0)

虽然不是在php中,但是这个sql可以处理你的第一个和第二个查询...并正确处理每个表盘返回最长的匹配条目。

select 
      PQ.clean_dst,
      PQ.dial_code,
      PQ.tele2id,
      @Rank := if( @lastDst = PQ.clean_dst, @Rank +1, 1 ) as dialRank,
      @lastDst := PQ.clean_dst as ForNextRowCompare
   from 
      ( SELECT distinct
              cdr.clean_dst,
              dc.dial_code,
              dc.tele2id,
              length( trim( dc.dial_code )) as Longest
           from 
              cdr
                 JOIN dialing_codes dc
                    on cdr.clean_dst like concat( dc.dial_code, '%' )
           order by
              cdr.clean_dst,
              Longest DESC ) PQ,
      ( select @lastDst := '',
               @Rank := 0 ) sqlvars
   having
      dialRank = 1

第一部分是内部查询,产生别名“PQ”(preQuery)。它将获得任何呼叫数据记录与其匹配的POSSIBLE拨号代码的不同组合列表。关键组件是按拨打的每个电话号码下订单,然后根据最长的拨号代码按降序排列。这将使用它将您的“1800”放在每个电话号码列表的顶部。

接下来是外部查询,其中应用了MySQL @variables。这些工作就像在线编程循环一样,用于“PQ”结果集中的每个记录。它分别以空白和零开始变量。

每条记录将其拨打的号码与最后拨打的号码记录进行比较(例如,您的1800和1多个返回集合)。如果它们是同一部手机,请在现有的@Rank中加1,否则,这是电话号码的变化...总是将电话号码更改回等级1.然后,它将@lastDst分配给电话号码刚处理完毕,它可以作为下一个被测试电话记录的基础。

最后是一个HAVING子句,只包括DialRank = 1

的子句

因此,根据您的记录集样本,查询将导致记录看起来像......

Dial Number    Dial_Code  Tele2ID   Longest  DialRank   ForNextRowCompare
18006927753    1800       1433      4        1          18006927753        <-- Keep this
18006927753    1          1422      1        2          18006927753
441138973356   441        1024      3        1          441138973356       <-- Keep this

每条评论的反馈。要处理您的更新,您可以将其包装起来

update cdr,
   ( full query ) as FromThisQuery
  where cdr.clean_dst = FromThisQuery.clean_dst
  set tele2id = FromThisQuery.tele2id