2016-05-04 2 views
1

У меня есть задача завершить, где мне нужно импортировать около 970 000 пользователей из чужой базы данных в наш. В исходной БД есть поле номера телефона, содержащее несколько телефонных номеров, объединенных в одну отвратительную строку.MS SQL - Как извлечь номер телефона из длинной несогласованной строки

Вот некоторые примеры данных:

|Home: 555-555-5555 Office: (555)-555-5555 Work: 5555555555| 
|Home: Office: 555\555-5555 Work: 555-555-5555| 
|Office: 555-555-5555 Home: (555)555-5555 some Comment here| 

Проблема, которые я бег в

  1. Порядок чисел противоречив
  2. Есть некоторые бесплатные текстовые комментарии валялись
  3. Некоторые номера телефонов имеют разное форматирование.

Я бы предпочел сделать это с помощью SQL, если это возможно, и я очень уверен, делая это эффективным образом с минимальной ручной настройкой.

В моей БД у нас есть отдельные столбцы для каждого типа номера телефона, поэтому мне в основном нужно разбить эти строки на соответствующие столбцы.

Скажите, пожалуйста, если я что-нибудь уберу.

+5

я бы не сделать это в SQL. Я бы сделал приложение, которое извлекает данные, дезинфицирует его и сохраняет в правильной модели. Попытка решить его в SQL только потребовала бы столько же времени, сколько было бы «легко». –

+1

Я полностью согласен с Аллан. Это будет ужасная боль в твоей ноу-хау, которую нужно делать в sql. –

+2

Согласовано. Выберите подходящий инструмент для работы. Эта работа требует сильных функций обработки текста, и в целом соглашается, что инструменты обработки текста T-SQL являются одними из самых бедных. –

ответ

1

В этом коде, вам потребуется 3 дополнительные столбцы для хранения новых телефонных номеров

Это логика в коде

  1. расщепляющие номера телефонов

  2. резки выкл. текст перед первым 3 последними 3 числами в результате сплит-вывода

  3. удаление нг чужеродные символы, используемые в номер телефона (только те, которые используются в образце)

  4. вставляя замены сепараторов «-» в положении 7 и 4

  5. группировки вверх данных

  6. обновление таблицы

образец данных:

DECLARE @t table 
    (phone varchar(500), home varchar(50), work varchar(50), office varchar(50)) 
INSERT @t(phone) values 
('Home: 555-555-5551 Office: (555)-555-5555 Work: 5555555552|'), 
('|Home: Office: 555\555-5555 Work: 555-555-5555|'), 
('|Office: 555-555-5555 Home: (555)555-5555 some Comment here|') 

Update:

;WITH CTE as 
(
    SELECT 
     nid,work, home, office, 
     t.c.value('.', 'VARCHAR(2000)') phone 
    FROM (
     SELECT 
      row_number() over(order by (select 1)) nid, work, home,office, 
      x = CAST('<t>' + 
       REPLACE(REPLACE(REPLACE(phone, 'Work', '</t><t>work') 
       ,'Office', '</t><t>Office'), 'Home', '</t><t>Home') 
       + '</t>' AS XML) 
     FROM @t -- replace @t with your table 
    ) a 
    CROSS APPLY x.nodes('/t') t(c) 
    WHERE t.c.value('.', 'VARCHAR(2000)') like '%[0-9][0-9][0-9]%' 
), CTE2 as 
(
SELECT 
work,max(case when phone like '%work%' then z end) over(partition by nid)nwork, 
home,max(case when phone like '%home%' then z end) over(partition by nid)nhome, 
office,max(case when phone like '%office%' then z end) over(partition by nid)noffice 
FROM cte t 
CROSS APPLY(SELECT REVERSE(SUBSTRING(phone,PATINDEX('%[0-9][0-9][0-9]%', phone), 20))x)y 
CROSS APPLY(SELECT STUFF(STUFF(REPLACE(REPLACE(REPLACE(REVERSE(
    SUBSTRING(x, PATINDEX('%[0-9][0-9][0-9]%', x), 20)), ')', ''), '\', ''), 
    '-', ''),7,0, '-'),4,0,'-')z)v ) 
UPDATE CTE2 
SET work = nwork, home = nhome, office = noffice 

SELECT home,work,office FROM @t 

Результат:

home   work   office 
555-555-5551 555-555-5552 555-555-5555 
NULL   555-555-5555 555-555-5555 
555-555-5555 NULL   555-555-5555 
+0

От OP - «Порядок номеров несовместим» - из этого (и третьего примера), я полагаю, они хотят знать, является ли каждый номер домашним, рабочим или служебным номером, в частности. –

+0

@Damien_The_Unbeliever спасибо, я пропустил это, попытаюсь исправить это –

+0

@Damien_The_Unbeliever Я исправил его –

1

Использование T-SQL для этой задачи не было бы лучшим выбором. Ближайшим решением было бы создание сборки CLR, которая использовала бы функциональность RegEx, доступную в .NET.

Однако вы также можете изучить Data Quality Services. Это компонент SQL Server, который был создан для этого конкретного типа задач - ручная очистка, унификация, дедупликация и т. Д. Однако для этого требуется BI или Enterprise edtion SQL Server.

+0

Спасибо за подсказку. Я использую SQL Server 2012 Enterprise, поэтому я должен использовать DQS для того, что мне нужно. Считаете ли вы, что быстрее просто написать небольшое консольное приложение для анализа этих данных или использования DQS? – Sage

+0

@Sage, я думаю, что ответ будет очень сильно зависеть от сложности ваших данных и количества различных форматов, с которыми вы можете столкнуться. Но да, DQS может иметь довольно крутую кривую обучения. Кроме того, это будет зависеть от того, является ли это одноразовым или непрерывным потоком данных, который необходимо поддерживать. Так что это действительно зависит от вас. –

Смежные вопросы