2010-06-23 2 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

+1

Итак, для каждого значения 'префикс'' p' его 'значительный' является самым коротким« префиксом », который начинается с' p'? – AakashM

+1

@AakashM - Правильно – veccy

ответ

2

Вы можете попробовать следующее (с помощью INSTR() и LENGTH() функции в MySQL):

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 | 

... 

Возможно, вы захотите запустить запрос UPDATE всякий раз, когда вы добавляете новую строку в свою таблицу numbers.

+0

Выглядит хорошо. Я собираюсь попробовать это позже – veccy

+1

Спасибо, хорошо и ясно – veccy

+0

FWIW в стандартном SQL, который не имеет функции INSTR(), вы можете использовать 'CAST (n1.prefix AS VARCHAR) LIKE CAST (n2.prefix AS VARCHAR) + '%' ' – onedaywhen

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; 
Смежные вопросы