1

嗨,我有 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

我需要获得 tele2id 以在 dial_code 中与 clean_dst 进行最接近的匹配,到目前为止我的最大努力是

$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

我究竟做错了什么?谢谢

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

4

2 回答 2

0

请尝试以下查询:

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

您不需要在 php.ini 中编写所有这些逻辑。MySQL 为您提供了在 SQL 中本地执行的函数和比较,这更简单、更简洁。

希望这可以帮助。

于 2013-09-28T20:20:10.750 回答
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 多个返回集的情况下)。如果它们是同一个电话,则将 1 添加到现有的 @Rank,否则,这是电话号码的更改...始终将电话号码更改回排名 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
于 2013-09-29T02:18:14.410 回答