2010-06-21 66 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