Hi I have 2 tables structured as follows
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
I need to get the tele2id for the closest match in dial_code against clean_dst my best effort so far is
$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()) {
Which I thought was working but on closer inspection it only returns the correct result the first time if a clean_dst is repeated
eg
clean_dst dial_code tele2id
18006927753 1800 1433
18006927753 1 1422
What am i doing wrong? Thanks
If it helps I need the result with the most matching digits?
Please try this query:
select dial_code, clean_dst from cdr c, dialing_codes d where c.clean_dst
like concat(d.dial_code, '%');
You don't need to code all that logic in php. MySQL gives you the functions and comparisons to do it natively in SQL, which is simpler and much more concise.
Hope this helps.
Although not in php, this one sql can handle your first and secondary query all in one... AND properly handle returning the longest matching entry per dial.
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
The first part is the inner query resulting in alias "PQ" (preQuery). It is getting a list of distinct combinations for any call data record to its matching POSSIBLE dial codes. Critical component is to put the order by each phone number dialed, THEN based on the longest dial code in descending order. This will put your "1800" at the top of the list per phone number using it.
Next comes the outer query where the MySQL @variables are applied. These work like in-line programming loop for you and goes for every record in the "PQ" result set. It starts the variables with blank and zero respectively.
Every record compares its dialed number to the last dialed number record (in cases like your 1800 and 1 multiple return sets). If they ARE the same phone, add 1 to the existing @Rank, otherwise, it is a change in phone numbers... always start a phone number change back to rank 1. THEN, it assigns the @lastDst to the phone number it just processed so it can be the basis of the next phone record being tested.
At the end is a HAVING clause to only include those of DialRank = 1
So, per your record set samples, the query would result in records looking something like...
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
Feedback per comment. TO handle your update, you can just wrap it up
update cdr,
( full query ) as FromThisQuery
where cdr.clean_dst = FromThisQuery.clean_dst
set tele2id = FromThisQuery.tele2id
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.