0

私は2つの電話番号を持っています。a-partyとb-partyで、最も一致する通話料金を見つけたいと思っています。

さまざまなa-partyおよびb-party番号と1分あたりの料金を含む通話料金の表があります。

通話料金を調べると、最初にa-partyで最も具体的な一致が見つかります。bパーティの一致が見つかった場合は、最も具体的なbパーティの一致からのレートが使用されます。a-partyのb-party一致が見つからない場合、次に最も具体的なa-party一致が調べられ、b-party一致があるかどうかが確認されます。一致するものが見つからない場合は、別のメッセージを返す必要があります。

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

これが私がこれまでに試みた方法です。これは非常に大まかなアウトラインです。ストアドプロシージャの作成経験は限られています。

これについてもっと良い方法があるかどうかについてのアドバイスを探しています。コールレートテーブルは非常に大きくなるため、二重のforループを使用すると非常に非効率になることが想像できます。

フィードバックをいただければ幸いです。

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  

これは、質問の結果の1つを除くすべてに一致します。

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 に答える