2010-06-21 79 views
3

我不知道如何解释我希望其他然后举了个例子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 
+0

好问题!我很感兴趣,看看这是否是(理性)在SQL中解决的。同时,你需要什么?你想找出国家代码吗?会有更简单的方法来做到这一点。 – 2010-06-21 22:22:11

+0

有什么标准来选择只是“阿根廷 - 移动”,并没有与阿根廷开头的其他国家的名字? – mdma 2010-06-21 22:24:03

+0

这只是一个示例部分。完整列表大约为20k行。我想从我的源数据中提取。出于兴趣,你怎么会得到国家代码很容易 – veccy 2010-06-21 22:32:36

回答

0

我发布实时运行的例子(在SQL Azure中方言):

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

请注意,这使用PATINDEX(这不是可移植到MySQL)来查找空间的第一次出现或' - '来首先对国家进行分类。然后它会在课堂上找到最短的 - 然后加入以获得结果。

+0

你的例子似乎已经奏效,但因为我没有运行该版本 – veccy 2010-06-21 23:08:50

+0

我不能使用该选项@veccy它只是用来确定等价类,所以你确定任何适当的机制将起作用。 – 2010-06-22 04:37:37

+0

想到我的脑海里只能对前缀进行排序以找到最短的denomiators,然后将前缀匹配到国家 – veccy 2010-06-22 10:00:48

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 
0

我想你可以通过归一国到它自己的场(和/或表,与一个国家ID)很长的路要走。从长远来看可能会有所帮助。

那么你就只需要做一个简单的

select distinct country_name, min(prefix) 
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 
0

假设前缀是一个字符串,

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

我不得不做类似的事情(但最长前缀),因为在工作中愚蠢选择“职业”的代码,其中“为$专业化”和“IST学院$”表示specalists和学生,有一些额外的信息.. 。分析数据需要类似于此的代码。 YMMV取决于你的RDBMS - 我在mysql上测试了类似于这个的东西。

+0

在语法解析之前,您可能需要多余的“GROUP BY country,prefix”,但是我不记得100% – tobyodavies 2010-10-13 23:00:59