0

我有两个电话号码,一个 a-party 和 b-party,我想找到最匹配的通话费率。

有一个呼叫费率表,其中包含各种 a 方和 b 方号码以及每分钟的费率。

在查找通话费率时,首先会找到参与方中最具体的匹配项。如果找到 b 方匹配,则使用最具体 b 方匹配的费率。如果没有为 a 方找到 b 方匹配,则查看下一个最具体的 a 方匹配以查看它是否具有 b 方匹配。如果未找到匹配项,则必须返回单独的消息。

i.e 
call_rates
a-party     b-party    rate_per_min
6495631234  619234     0.10
6495631     6192       0.12
649         61923      0.09
649         61         0.16

对于上述通话费率,请致电:

a-party: 6495631234b-party: 619234567返回rate_per_min: 0.10

a-party: 6495631111b-party: 619234567返回rate_per_min: 0.12

a-party: 6495631111b-party: 611112345返回rate_per_min: 0.16

a-party: 6495631111b-party: 619234566返回rate_per_min: 0.09

到目前为止,这就是我尝试的方式。这是一个非常粗略的大纲。我在编写存储过程方面经验有限。

我只是在寻找一些关于是否有更好的方法来解决这个问题的建议。调用率表会非常大,所以我可以想象双循环会非常低效。

任何反馈将不胜感激。

DELIMITER //
DROP PROCEDURE IF EXISTS `get_rate`;
CREATE PROCEDURE `get_rate` (a VARCHAR(45), b VARCHAR(45), OUT rate VARCHAR(45))
get_r:BEGIN
    DECLARE i, j INT;
    DECLARE match_string, result, temp_string VARCHAR(255);

    SET j = LENGTH(b);
    SET i = LENGTH(a);

    WHILE i > 0 DO
        SET temp_string = SUBSTRING(a,0,i);
        SET result = (SELECT * FROM call_rate_overrides WHERE a_party LIKE CONCAT(temp_string, '%'));
        WHILE j > 0 DO
            SET temp_string = SUBSTRING(b,0,j);
            SET match_string = (SELECT * FROM call_rate_overrides WHERE b_party LIKE CONCAT(temp_string,'%'));
            IF ISNOTNULL(match_string) THEN
                SET rate = match_string;
                LEAVE get_r;
            END IF;  
            SET j = j - 1;
        END WHILE;
    
        SET i = i - 1;
    END WHILE;
END //
4

2 回答 2

2

最终以这种方式解决了问题:

SELECT     s.a_party, s.b_party, (
           SELECT  cr.rate_per_min
           FROM call_rate_overrides cr
           WHERE s.a_party LIKE CONCAT(cr.a_party, '%')
           AND s.b_party   LIKE CONCAT(cr.b_party,  '%')
           ORDER BY LENGTH(cr.a_party) + LENGTH(cr.b_party) DESC, cr.rate_per_min
           LIMIT 1
     ) as rate_per_min
FROM call_usages s 

其中呼叫用法是 a 方和 b 方的表。它通过根据匹配的长度对它们进行排序来匹配全长方的最长数据库条目。

于 2012-10-09T02:55:34.157 回答
0

这个查询:

SELECT 
  s.a_party,
  s.b_party,
  cr.rate_per_min
FROM
    call_rate_overrides cr
INNER JOIN
    call_usages s ON 
        s.a_party LIKE CONCAT(cr.a_party, '%') AND
        s.b_party LIKE CONCAT(cr.b_party, '%')
INNER JOIN
(
  SELECT 
    s.a_party,
    s.b_party,
    MAX(LENGTH(cr.a_party) + LENGTH(cr.b_party)) as len
  FROM
    call_rate_overrides cr
  INNER JOIN
    call_usages s ON 
      s.a_party LIKE CONCAT(cr.a_party, '%') AND
      s.b_party LIKE CONCAT(cr.b_party, '%')
  GROUP BY
    s.a_party,
    s.b_party
) d ON
    d.a_party = s.a_party AND
    d.b_party = s.b_party AND
    d.len = LENGTH(cr.a_party) + LENGTH(cr.b_party)
ORDER BY
  d.a_party,
  d.b_party

返回

a_party     b_party     rate_per_min
6495631111  611112345   0.16
6495631111  619234566   0.12
6495631111  619234567   0.12
6495631234  619234567   0.10  

与您的问题中除一个结果之外的所有结果相匹配:

a-party: 6495631111 to b-party: 619234566 would return the rate_per_min: 0.09

如果你仔细看,你会发现正确的答案,确实是 0.12。

有关工作示例,请参阅http://sqlfiddle.com/#!2/b402c/13 。

于 2012-10-04T04:58:24.903 回答