所以我有一个客户数据库。我运行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()
提取所有名称。我不知道如何使用它,希望我能得到一些帮助。
我怀疑你的代码有TRY/CATCH
,或者你正在吞下/抑制/忽略错误。你应该得到 4 行,然后是一个大丑陋的错误消息:
Msg 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;
如果未使用逗号,则第一个条件仅返回原始值。