mysql最短长度匹配

时间:2010-06-21 22:18:00

标签: sql mysql

我不知道如何解释我想要的东西,然后给出一个例子

country                           prefix
Argentina-Mobile                  549
Argentina-Neuquen                 54299
Argentina-Rosario                 54341
Argentina-Salta                   54387
Argentina-Santa Fe                54342
Argentina-Tucuman                 54381
Armenia                           374
Armenia Mobile-K-Telecom          37477
Armenia Mobile-K-Telecom          37493
Armenia Mobile-K-Telecom          37494
Armenia Mobile-K-Telecom          37498
Armenia-Karabakh                  37447
Armenia-Mobile                    37455
Armenia-Mobile                    3749
Armenia-Yerevan                   37410
Aruba                             297
Aruba-Mobile                      29756
Aruba-Mobile                      29759
Aruba-Mobile                      29766
Aruba-Mobile                      29769
Aruba-Mobile                      29796
Aruba-Mobile                      29799
Aruba-Mobile-Digicell             29773
Aruba-Mobile-Digicell             29774
Aruba-Mobile-MIO                  297600
Aruba-Mobile-MIO                  297622
Ascension Island                  247
Australia                         61
Australia-Adelaide/Perth          61861
Australia-Adelaide/Perth          61862
Australia-Adelaide/Perth          61863

我想对前缀运行查询以获取最短父前缀

的列表
country                  prefix
Argentina -Mobile        549
Armenia                  374
Aruba                    297
Australia                61

5 个答案:

答案 0 :(得分:1)

这比我想象的要容易。您只需按国家/地区分组,然后使用MIN()

虽然这对于每个字段都有一个国家/地区代码列,而不是必须解析国家/地区文本,这可能会导致错误,但这样会容易得多,并且不容易出错。

SELECT t2.country, MIN(CAST(t1.prefix AS SIGNED)) AS prefix FROM MyTable t1
LEFT JOIN MyTable t2
ON t2.prefix = t1.prefix
GROUP BY
  IF(
     INSTR(t1.country, ' mobile') = 0 AND INSTR(t1.country, '-') = 0,
     t1.country,
     IF(
        INSTR(t1.country, ' mobile') > 0 AND INSTR(t1.country, '-') > 0,
        IF(
           INSTR(t1.country, ' mobile') > INSTR(t1.country, '-'),
           LEFT(t1.country, INSTR(t1.country, '-') - 1),
           LEFT(t1.country, INSTR(t1.country, ' mobile') - 1)
          ),
        IF(
           INSTR(t1.country, ' mobile') > INSTR(t1.country, '-'),
           LEFT(t1.country, INSTR(t1.country, ' mobile') - 1),
           LEFT(t1.country, INSTR(t1.country, '-') - 1)
          )
       )
    )
ORDER BY t2.country

收率:

country           prefix
Argentina-Mobile  549
Armenia           374
Aruba             297
Ascension Island  247
Australia         61

答案 1 :(得分:0)

我发布了一个实时运行的示例(在SQL Azure方言中):

https://data.stackexchange.com/stackoverflow/query/4822

请注意,这会使用PATINDEX(这不能移植到MySQL)来查找空格的第一个匹配项,或者使用“ - ”来首先对国家进行分类。然后它找到类中最短的 - 然后加入以获得结果。

答案 2 :(得分:0)

我认为你可以通过将国家标准化为自己的领域(和/或表格,具有国家ID)来实现目标。从长远来看可能会有所帮助。

然后你只需要做一个简单的

select distinct country_name, min(prefix)

答案 3 :(得分:0)

这是MS SQL Server,但想法是:

WITH countries AS (
    SELECT 
        LEFT(country, CHARINDEX('-', RTRIM(COUNTRY) + '-') - 1) AS name, 
        LEN(prefix) AS prefixlen 
    FROM
        countryprefix
),
winners as (
    SELECT 
        name, MIN(prefixlen) as shortest
    FROM
        countries
    GROUP BY
        name
)
SELECT 
    country, MIN(prefix)
FROM
    countryprefix cp inner join winners  ON
        LEFT(cp.country, CHARINDEX('-', cp.country + '-') - 1) = winners.name AND
        LEN(prefix) = winners.shortest 
GROUP BY
    country

输出:

Argentina-Mobile            549
Armenia                 374
Armenia Mobile-K-Telecom    37477
Aruba                   297
Ascension Island            247
Australia                   61

答案 4 :(得分:0)

假设前缀是一个字符串,

SELECT country, prefix from countries 
WHERE country LIKE "searchTerm%"
HAVING length(prefix) = min(length(prefix))

我必须做类似的事情(但是前缀最长),因为工作中愚蠢地选择了“职业”代码,其中“是$ Specialization”和“ist $ Faculty”表示specalists和学生,还有一些额外的信息......分析该数据需要与此类似的代码。 YMMV取决于您的RDBMS - 我在mysql上测试了类似于此的东西。