2010-06-23 76 views
3

我有國家dialcode一列數字我想前綴過濾到最左邊的撥碼SQL可以對數字的重要部分進行排序嗎?

這是源列:

prefix 
------ 
542 
54299 
374 
37477 
37493 
37494 
37498 
37447 
37455 
3749 
37410 
297 
29756 
29759 
29766 
29769 
29796 
29799 
29773 
29774 
297600 
297622 
247 
61 
61861 
61862 
61863 

這是我想要的結果的一個例子。 SQL可以很容易地做到這一點,以及如何或有更好的方法。請記住將有大約30K行

significant  prefix 
---------------------- 
542    542 
542    54299 
374    374 
374    37477 
374    37493 
374    37494 
374    37498 
374    37447 
374    37455 
374    3749 
374    37410 
297    297 
297    29756 
297    29759 
297    29766 
297    29769 
297    29796 
297    29799 
297    29773 
297    29774 
297    297600 
297    297622 
247    247 
61    61 
61    61861 
61    61862 
61    61863 
+0

應該如何MySQL的知道什麼是重要的數字,什麼是前綴?每個有效數字總是最大3位數? – Konerak 2010-06-23 09:23:03

+1

因此,對於每個'前綴'值'p',它的'significant'是'p'開頭的最短'前綴'? – AakashM 2010-06-23 09:24:33

+1

@AakashM - 正確的 – veccy 2010-06-23 09:30:29

回答

2

你可能想嘗試以下(使用MySQL的INSTR()LENGTH()功能):

SELECT (SELECT prefix 
     FROM  numbers n2 
     WHERE INSTR(n1.prefix, n2.prefix) = 1 
     ORDER BY LENGTH(n2.prefix) 
     LIMIT 1 
     ) AS significant, 
     n1.prefix 
FROM numbers n1; 

退房@onedaywhen's answer對於上述的ANSI SQL版本查詢。

測試用例:

CREATE TABLE numbers (prefix int); 

INSERT INTO numbers VALUES (542); 
INSERT INTO numbers VALUES (54299); 
INSERT INTO numbers VALUES (374); 
INSERT INTO numbers VALUES (37477); 
INSERT INTO numbers VALUES (37493); 
INSERT INTO numbers VALUES (37494); 
INSERT INTO numbers VALUES (37498); 
INSERT INTO numbers VALUES (37447); 
INSERT INTO numbers VALUES (37455); 
INSERT INTO numbers VALUES (3749); 
INSERT INTO numbers VALUES (37410); 
INSERT INTO numbers VALUES (297); 
INSERT INTO numbers VALUES (29756); 
INSERT INTO numbers VALUES (29759); 
INSERT INTO numbers VALUES (29766); 
INSERT INTO numbers VALUES (29769); 
INSERT INTO numbers VALUES (29796); 
INSERT INTO numbers VALUES (29799); 
INSERT INTO numbers VALUES (29773); 
INSERT INTO numbers VALUES (29774); 
INSERT INTO numbers VALUES (297600); 
INSERT INTO numbers VALUES (297622); 
INSERT INTO numbers VALUES (247); 
INSERT INTO numbers VALUES (61); 
INSERT INTO numbers VALUES (61861); 
INSERT INTO numbers VALUES (61862); 
INSERT INTO numbers VALUES (61863); 

結果:

+-------------+--------+ 
| significant | prefix | 
+-------------+--------+ 
|   542 | 542 | 
|   542 | 54299 | 
|   374 | 374 | 
|   374 | 37477 | 
|   374 | 37493 | 
|   374 | 37494 | 
|   374 | 37498 | 
|   374 | 37447 | 
|   374 | 37455 | 
|   374 | 3749 | 
|   374 | 37410 | 
|   297 | 297 | 
|   297 | 29756 | 
|   297 | 29759 | 
|   297 | 29766 | 
|   297 | 29769 | 
|   297 | 29796 | 
|   297 | 29799 | 
|   297 | 29773 | 
|   297 | 29774 | 
|   297 | 297600 | 
|   297 | 297622 | 
|   247 | 247 | 
|   61 |  61 | 
|   61 | 61861 | 
|   61 | 61862 | 
|   61 | 61863 | 
+-------------+--------+ 
27 rows in set (0.00 sec) 

應該,即使你使用的是varchar來存儲數字工作。


UPDATE:

至於性能,你可能要考慮你的表緩存significant部分:

CREATE TABLE numbers (prefix int, significant int); 

-- Fill in the prefixes, leaving the significant field as NULL. 

然後,你可以生成significant場如下(使用MySQL):

UPDATE numbers n 
JOIN (SELECT (SELECT prefix 
        FROM  numbers n2 
        WHERE INSTR(n1.prefix, n2.prefix) = 1 
        ORDER BY LENGTH(n2.prefix) 
        LIMIT 1 
       ) AS significant, 
       n1.prefix 
     FROM numbers n1 
     ) s ON (s.prefix = n.prefix) 
SET n.significant = s.significant; 

SELECT * FROM numbers; 
+--------+-------------+ 
| prefix | significant | 
+--------+-------------+ 
| 542 |   542 | 
| 54299 |   542 | 
| 374 |   374 | 
| 37477 |   374 | 
| 37493 |   374 | 
| 37494 |   374 | 

... 

無論何時在numbers表中添加新行,您都可能想要運行UPDATE查詢。

+0

看起來不錯。我將在稍後嘗試此操作 – veccy 2010-06-23 10:20:25

+1

謝謝,清晰明瞭 – veccy 2010-06-23 11:37:39

+0

標準SQL中的FWIW,它沒有INSTR()函數,可以使用'CAST(n1.prefix AS VARCHAR)LIKE CAST(n2.prefix AS VARCHAR )+'%'' – onedaywhen 2010-06-23 12:48:22

1

這個問題只有一個「SQL」標籤(沒有「MySQL的」標籤),所以這裏是一個使用標準SQL提議的解決方案,假設prefix是在表中INTEGER列名爲Numbers

SELECT (
     SELECT MIN(N2.prefix) 
      FROM Numbers AS N2 
     WHERE CAST(N1.prefix AS VARCHAR) LIKE CAST(N2.prefix AS VARCHAR) + '%' 
     ) AS significant, 
     N1.prefix 
    FROM Numbers AS N1; 
相關問題