Надежный способ сделать это (надежный с точки зрения «правильной сортировки данных», а не «решения вашей общей проблемы») состоит в том, чтобы разделить данные по названию улицы и номеру дома и отсортировать их обоих самостоятельно. , Но для этого нужно знать, где начинается номер дома. И это сложная часть - сделать предположение, которое наилучшим образом соответствует вашим данным.
Вы должны использовать что-то вроде следующего для рефакторинга ваших данных и отныне хранить номер дома в отдельном поле. Все это жонглирование строк не будет работать слишком хорошо, когда дело доходит до сортировки больших наборов данных.
Предполагая, что это последняя вещь в названии улицы, и она содержит число:
DECLARE @test TABLE
(
street VARCHAR(100)
)
INSERT INTO @test (street) VALUES('Street')
INSERT INTO @test (street) VALUES('Street 1A')
INSERT INTO @test (street) VALUES('Street1 12B')
INSERT INTO @test (street) VALUES('Street 22A')
INSERT INTO @test (street) VALUES('Street1 200B-8a')
INSERT INTO @test (street) VALUES('')
INSERT INTO @test (street) VALUES(NULL)
SELECT
street,
CASE
WHEN LEN(street) > 0 AND CHARINDEX(' ', REVERSE(street)) > 0
THEN CASE
WHEN RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1) LIKE '%[0-9]%'
THEN LEFT(street, LEN(street) - CHARINDEX(' ', REVERSE(street)))
END
END street_part,
CASE
WHEN LEN(street) > 0 AND CHARINDEX(' ', REVERSE(street)) > 0
THEN CASE
WHEN RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1) LIKE '%[0-9]%'
THEN RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1)
END
END house_part,
CASE
WHEN LEN(street) > 0 AND CHARINDEX(' ', REVERSE(street)) > 0
THEN CASE
WHEN RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1) LIKE '%[0-9]%'
THEN CASE
WHEN PATINDEX('%[a-z]%', LOWER(RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1))) > 0
THEN CONVERT(INT, LEFT(RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1), PATINDEX('%[^0-9]%', LOWER(RIGHT(street, CHARINDEX(' ', REVERSE(street)) - 1))) - 1))
END
END
END house_part_num
FROM
@test
ORDER BY
street_part,
house_part_num,
house_part
Это предполагает следующие условия:
- адрес улицы может иметь номер дома
- номер дома должен быть последним в адресе улицы (без "525 Monroe Av.")
- номер дома должен начинаться с цифры для правильной сортировки
- номер дома может быть диапазоном ("200-205"), это будет отсортировано ниже 200
- номер дома не должен содержать пробелов или распознавания не удается (Когда вы просматриваете свои данные, вы можете применить что-то вроде
REPLACE(street, ' - ', '-')
для предварительной очистки общих шаблонов.)
- все это все еще приближение, которое, безусловно, отличается от того, как оно будет выглядеть в телефонной книге, например