2010-06-23 106 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; 
相关问题