Разбор столбца для переключения имен с помощью patindex
Итак, у меня есть база данных клиентов. я бегу SELECT * FROM MyTable
он возвращает мне несколько столбцов, одним из которых является имя. Выглядит так:
"Doe, John"
"Jones, Bill"
"Smith, Mike"
"Johnson, Bob"
"Harry Smith"
"Black, Linda"
"White, Laura"
и т.д. Некоторые фамилия, имя. Другие - это имя, фамилия.
Мой босс хочет, чтобы я перевернул имена, чтобы они были первыми, а потом последними.
Итак, я запустил это:
SELECT SUBSTRING(Column_Name, CHARINDEX(',', Column_Name) + 2, LEN(Name) - CHARINDEX(',', Column_Name) + 1) + ' ' + SUBSTRING(Column_Name, 1, CHARINDEX(',', Column_Name) - 1) FROM MyTable
Проблема в том, что когда я запускаю это, он запускает только имена, пока не найдет то, которое ему не нужно переворачивать. Таким образом, в приведенном выше примере это дало бы мне только первые четыре имени, а не все.
Мне было предложено использовать PATINDEX()
вытащить все имена. Я не знаю, как использовать это, и надеялся, что смогу помочь с этим.
2 ответа
Я подозреваю, что ваш код имеет TRY/CATCH
или вы иначе глотаете / подавляете / игнорируете ошибки. Вы должны получить 4 строки назад и затем большое уродливое сообщение об ошибке:
Сообщение 537, уровень 16, состояние 2
Недопустимый параметр длины, переданный в функцию LEFT или SUBSTRING.
Проблема в том, что ваше выражение предполагает, что ,
всегда существует. Вы должны удовлетворить это либо отфильтровывая строки, которые не содержат ,
(хотя это не очень надежно, поскольку выражение может быть использовано перед фильтром), или следующим образом, где вы принимаете различные решения о том, как собрать строку в зависимости от того, ,
найден или нет:
DECLARE @x TABLE(y VARCHAR(255));
INSERT @x VALUES
('Doe, John'),
('Jones, Bill'),
('Smith, Mike'),
('Johnson, Bob'),
('Harry Smith'),
('Black, Linda'),
('White, Laura');
SELECT LTRIM(SUBSTRING(y, COALESCE(NULLIF(CHARINDEX(',',y)+2,2),1),255))
+ RTRIM(' ' + LEFT(y, COALESCE(NULLIF(CHARINDEX(',' ,y)-1,-1),0)))
FROM @x;
Результаты:
John Doe
Bill Jones
Mike Smith
Bob Johnson
Harry Smith
Linda Black
Laura White
В этом случае вам не нужен PATINDEX, хотя его можно использовать. Я бы взял ваше выражение, чтобы перевернуть имена и поместить его в выражение CASE.
DECLARE @MyTable TABLE
(
Name VARCHAR(64) NOT NULL
);
INSERT @MyTable(Name)
VALUES
('Doe, John'),
('Jones, Bill'),
('Smith, Mike'),
('Johnson, Bob'),
('Harry Smith'),
('Black, Linda'),
('White, Laura');
SELECT
CASE
WHEN CHARINDEX(',', Name, 1) = 0 THEN Name
ELSE SUBSTRING(Name, CHARINDEX(',', Name) + 2, LEN(Name) - CHARINDEX(',', Name) + 1)
+ ' ' + SUBSTRING(Name, 1, CHARINDEX(',', Name) - 1)
END AS [Name]
FROM @MyTable;
Первое условие просто возвращает исходное значение, если запятая не использовалась.