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

これまでの最善の努力は、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

私は何を間違っていますか?ありがとう

それが役立つ場合、最も一致する数字の結果が必要ですか?

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 ですべてのロジックをコーディングする必要はありません。MySQL は、SQL でネイティブに実行するための関数と比較を提供します。これは、より単純ではるかに簡潔です。

お役に立てれば。

于 2013-09-28T20:20:10.750 に答える
0

PHP にはありませんが、この 1 つの SQL で最初と 2 番目のクエリをすべて 1 つに処理できます...さらに、ダイヤルごとに最も一致するエントリを返すことを適切に処理します。

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) になる内部クエリです。一致する可能性のあるダイヤル コードに対する通話データ レコードの個別の組み合わせのリストを取得しています。重要なコンポーネントは、ダイヤルされた各電話番号で順序を付けることです。次に、最も長いダイヤル コードに基づいて降順で並べます。これにより、「1800」が電話番号ごとのリストの一番上に表示されます。

次は、MySQL @variables が適用される外側のクエリです。これらはインライン プログラミング ループのように機能し、「PQ」結果セットのすべてのレコードに適用されます。変数はそれぞれ空白とゼロで始まります。

すべてのレコードは、ダイヤルされた番号を最後にダイヤルされた番号レコードと比較します (1800 および 1 の複数のリターン セットなどの場合)。それらが同じ電話である場合は、既存の @Rank に 1 を追加します。それ以外の場合は、電話番号の変更です...常に電話番号の変更を開始してランク 1 に戻します。次に、@lastDst を電話番号に割り当てます。処理されたばかりなので、テストされる次の電話記録の基礎になることができます。

最後に、DialRank = 1 のものだけを含める HAVING 句があります。

したがって、レコードセットのサンプルごとに、クエリは次のようなレコードになります...

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