Попробуйте что-то вроде этого:
WITH AreaCode (A) AS (
SELECT '[0-9][0-9][0-9][-.]'
UNION ALL SELECT '([0-9][0-9][0-9])-'
), Prefix (P) AS (
SELECT '[0-9][0-9][0-9]-'
), Last4 (L) AS (
SELECT '[0-9][0-9][0-9][0-9]'
), Ext1 (E1) AS (
SELECT ' x'
UNION ALL SELECT ' Ext.'
UNION ALL SELECT ' ext'
), Ext2 (E2) AS (
UNION ALL SELECT '[0-9][0-9]'
UNION ALL SELECT '[0-9][0-9][0-9]'
UNION ALL SELECT '[0-9][0-9][0-9][0-9]'
), Extension (E) AS (
SELECT ''
UNION ALL SELECT E1 + E2 FROM Ext1 CROSS JOIN Ext2
),
SELECT *
FROM
YourTable Y
WHERE NOT EXISTS (
SELECT *
FROM
AreaCode
CROSS JOIN Prefix
CROSS JOIN Last4
CROSS JOIN Extension
WHERE
Y.PhoneNumber LIKE AreaCode + Prefix + Last4 + Extension
);
Если вы найдете шаблоны, которые действительны, но не охватываются запросом, добавьте их к показанным деталям и частям. Если вы найдете что-то, что должно быть вместе в двух частях, то смоделируйте это после Extension CTE (который отсутствует или является комбинацией Ext1 и Ext2). Если вам нужно поддерживать международные номера, и они имеют разные шаблоны (не соответствующие США 3-3-4), вам потребуется некоторый анализ и правильная корреляция, чтобы привести правильные коды стран в соответствие с правильными шаблонами. Например, я знаю, что в некоторых частях Бразилии это действительное число: +55 85 1234-5678 (код страны 55, код города, состоящий из двух цифр, затем шаблон 4-4).
Еще один метод, который поможет вам проанализировать ваши данные:
WITH Patterns (P) AS (
SELECT
Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(
PhoneNumber,
'1', '0'), '2', '0'), '3', '0'), '4', '0'),
'5', '0'), '6', '0'), '7', '0'), '8', '0'), '9', '0'
)
)
SELECT P, Count(*)
FROM Patterns
GROUP BY P;
Это может помочь вам понять, на что похожи ваши данные, игнорируя фактические различия телефонных номеров между каждой строкой и обращая внимание только на расположение и количество цифр. Если имеется много буквенных символов, попробуйте начать замену допустимых шаблонов (таких как «ext») значением, не найденным в списке, чтобы можно было свести оставшиеся ложные данные во что-то, что можно проанализировать с помощью аналогичного Replace()
за каждую букву в алфавите.