MySQL匹配连接表

时间:2017-08-27 16:48:55

标签: mysql join prefix

我们有2个表," callsdb "拿着电话记录和" regionsdb "持有区域相关的前缀。 我们需要做的是生成一个匹配" callsdb.destination_number "使用 LONGEST 前缀" regionsdb.country_prefix "。

注意:

1)" callsdb"中的电话号码可能会也可能不会拥有" 1001"前缀。

2)" callsdb"中的电话号码有额外的" 00"国家/地区前缀前的前缀。

我们尝试了以下查询,但性能极差。 有没有更快的方法来实现这一目标?

SELECT 
    uid, call_date, destination, name, country_prefix, duration, unit_cost 
FROM 
    callsdb.calls 
INNER JOIN 
    regionsdb.regions 
ON 
(
    (
        (calls.destination_number LIKE CONCAT('100100', regions.country_prefix, '%')) 
        AND 
        (
            LENGTH(regions.country_prefix) = 
            (
                SELECT MAX(LENGTH(regions.country_prefix))
                FROM regionsdb.regions
                WHERE calls.destination_number LIKE CONCAT('100100', regions.country_prefix, '%')
            )
        )
    )
    OR  
    (
        (calls.destination_number LIKE CONCAT('00', regions.country_prefix, '%')) 
        AND 
        (
            LENGTH(regions.country_prefix) = 
            (
                SELECT MAX(LENGTH(regions.country_prefix))
                FROM regionsdb.regions
                WHERE calls.destination_number LIKE CONCAT('00',regions.country_prefix, '%')
            )
        )
    )
)
ORDER BY call_date DESC;

修改

通过改变" ON&#34>来减少执行时间。部分查询。但它仍然太慢了!

ON 
(
    (
        (IF(calls.destination_number LIKE '1001%', SUBSTRING(calls.destination_number, 5), calls.destination_number) LIKE CONCAT('00', regions.country_prefix, '%')) 
        AND 
        (
            LENGTH(regions.country_prefix) = 
            (
                SELECT MAX(LENGTH(regions.country_prefix))
                FROM regionsdb.regions
                WHERE IF(calls.destination_number LIKE '1001%', SUBSTRING(calls.destination_number, 5), calls.destination_number) LIKE CONCAT('00', regions.country_prefix, '%')
            )
        )
    )
)

编辑2: 在选择" dst"更正为"目的地"。

1 个答案:

答案 0 :(得分:1)

您可以将group bygroup_concat结合使用,这样可以按照regions下降的顺序连接country_prefix表中的字段。然后你可以提取第一个。

我将假设字段nameunit_cost来自regions表,如果其他字段也是如此,则对它们应用相同的逻辑。 group by子句应列出calls表中的所有选定字段,或至少列出关键字段:

select     c.uid, c.call_date, c.dst, 
           substring_index(
                group_concat(r.name order by length(r.country_prefix) desc), 
                ',', 1) as name, 
           substring_index(
                group_concat(r.country_prefix order by length(r.country_prefix) desc), 
                ',', 1) as country_prefix, 
           c.duration,
           substring_index(
                group_concat(format(r.unit_cost, 2) 
                             order by length(r.country_prefix) desc),
                ',', 1) as unit_cost 
from       callsdb.calls c
inner join regionsdb.regions r
        on (left(c.destination_number, 6 + length(r.country_prefix))
              = concat('100100', r.country_prefix)
           or mid(c.destination_number, 3, length(r.country_prefix))
              = r.country_prefix
           )
group by   c.uid,
           c.call_date,
           c.dst,
           c.duration