CHARINDEX 的 RIGHT 选择不正确
RIGHT of CHARINDEX not selecting correctly
我正在尝试解析一个姓氏字段,该字段可能有两个姓氏,由空白 space ' ' 或连字符 '-' 分隔,或者它可能只有一个名字。
这是我用来执行此操作的方法:
select top 1000
BENE_FIRST_NAME,
BENE_LAST_NAME,
FirstNm =
case
when BENE_FIRST_NAME like '% %' then
left(BENE_FIRST_NAME, CHARINDEX(' ', BENE_FIRST_NAME))
when BENE_FIRST_NAME like '%-%' then
left(BENE_FIRST_NAME, CHARINDEX('-', BENE_FIRST_NAME))
else BENE_FIRST_NAME
end,
LastNm =
case
when BENE_LAST_NAME like '% %' then
right(BENE_LAST_NAME, CHARINDEX(' ', BENE_LAST_NAME))
when BENE_LAST_NAME like '%-%' then
right(BENE_LAST_NAME, CHARINDEX('-', BENE_LAST_NAME))
else BENE_LAST_NAME
end,
CharIndxDash = CHARINDEX('-', BENE_LAST_NAME),
CharIndxSpace = CHARINDEX(' ', BENE_LAST_NAME)
from xMIUR_Elig_Raw_v3
以下是一些结果:
BENE_FIRST_NAME
BENE_LAST_NAME
FirstNm
LastNm
CharIndxDash
CharIndxSpace
JUANA
PEREZ-MARTINEZ
JUANA
RTINEZ
6
0
EMILIANO
PICENO ESPINOZA
EMILIANO
SPINOZA
0
7
JULIAN
NIETO-CARRENO
JULIAN
ARRENO
6
0
EMILY
SALMERON TERRIQUEZ
EMILY
TERRIQUEZ
0
9
CHARINDEX 似乎选择了正确的位置,但它并未将所有 CHAR 引入该位置的右侧。有时它像在上一张唱片中一样工作。但有时会差 1。有时会差 2。有什么想法吗?
你的姓氏逻辑没有意义..
RIGHT 从字符串右边取 N 个字符
CHARINDEX 给出字符从字符串左侧算起的位置
你不能用它从左边找到一个位置,然后从字符串右边取那个数量的字符
这是一个名字:
JOHN MALKOVICH
space在5处。如果你从右边取5个字符,你得到OVICH。 space 之前的名字越短,space 之后的名字越长,从姓氏
中得到的字符就越少
也许你的意思是在那里放一个LEN,这样你就可以用字符串长度减去space的索引。你也可以在调用SUBSTRING时使用它作为起始索引,并告诉SQLS取 9999 个字符(比剩余字符串长的任何数字),它将占用字符串的末尾
SUBSTRING(name, CHARINDEX(' ', name)+1, 9999)
如果您需要 select 姓氏的一部分在 space/hyphen 之后,您需要获取长度为 total_lenght - space_position
:
的字符串的正确部分
...
LastNm =
case
when BENE_LAST_NAME like '% %' then
right(BENE_LAST_NAME, LEN(BENE_LAST_NAME) - CHARINDEX(' ', BENE_LAST_NAME))
when BENE_LAST_NAME like '%-%' then
right(BENE_LAST_NAME, LEN(BENE_LAST_NAME) -CHARINDEX('-', BENE_LAST_NAME))
else BENE_LAST_NAME
end,
...
我认为您可以大大简化您的代码。下面考虑一个不同但具有代表性的样本数据
with data (name) as
(select 'first-last' union select 'first last' union select 'firstlast'),
data_prepped (name, indx) as
(select name,coalesce(nullif(charindex(' ', name)+charindex('-', name),0),len(name))
from data)
select name,
left(name, indx-1) as part1,
right(name, indx) as part2
from data_prepped
我正在尝试解析一个姓氏字段,该字段可能有两个姓氏,由空白 space ' ' 或连字符 '-' 分隔,或者它可能只有一个名字。
这是我用来执行此操作的方法:
select top 1000
BENE_FIRST_NAME,
BENE_LAST_NAME,
FirstNm =
case
when BENE_FIRST_NAME like '% %' then
left(BENE_FIRST_NAME, CHARINDEX(' ', BENE_FIRST_NAME))
when BENE_FIRST_NAME like '%-%' then
left(BENE_FIRST_NAME, CHARINDEX('-', BENE_FIRST_NAME))
else BENE_FIRST_NAME
end,
LastNm =
case
when BENE_LAST_NAME like '% %' then
right(BENE_LAST_NAME, CHARINDEX(' ', BENE_LAST_NAME))
when BENE_LAST_NAME like '%-%' then
right(BENE_LAST_NAME, CHARINDEX('-', BENE_LAST_NAME))
else BENE_LAST_NAME
end,
CharIndxDash = CHARINDEX('-', BENE_LAST_NAME),
CharIndxSpace = CHARINDEX(' ', BENE_LAST_NAME)
from xMIUR_Elig_Raw_v3
以下是一些结果:
BENE_FIRST_NAME | BENE_LAST_NAME | FirstNm | LastNm | CharIndxDash | CharIndxSpace |
---|---|---|---|---|---|
JUANA | PEREZ-MARTINEZ | JUANA | RTINEZ | 6 | 0 |
EMILIANO | PICENO ESPINOZA | EMILIANO | SPINOZA | 0 | 7 |
JULIAN | NIETO-CARRENO | JULIAN | ARRENO | 6 | 0 |
EMILY | SALMERON TERRIQUEZ | EMILY | TERRIQUEZ | 0 | 9 |
CHARINDEX 似乎选择了正确的位置,但它并未将所有 CHAR 引入该位置的右侧。有时它像在上一张唱片中一样工作。但有时会差 1。有时会差 2。有什么想法吗?
你的姓氏逻辑没有意义..
RIGHT 从字符串右边取 N 个字符
CHARINDEX 给出字符从字符串左侧算起的位置
你不能用它从左边找到一个位置,然后从字符串右边取那个数量的字符
这是一个名字:
JOHN MALKOVICH
space在5处。如果你从右边取5个字符,你得到OVICH。 space 之前的名字越短,space 之后的名字越长,从姓氏
中得到的字符就越少也许你的意思是在那里放一个LEN,这样你就可以用字符串长度减去space的索引。你也可以在调用SUBSTRING时使用它作为起始索引,并告诉SQLS取 9999 个字符(比剩余字符串长的任何数字),它将占用字符串的末尾
SUBSTRING(name, CHARINDEX(' ', name)+1, 9999)
如果您需要 select 姓氏的一部分在 space/hyphen 之后,您需要获取长度为 total_lenght - space_position
:
...
LastNm =
case
when BENE_LAST_NAME like '% %' then
right(BENE_LAST_NAME, LEN(BENE_LAST_NAME) - CHARINDEX(' ', BENE_LAST_NAME))
when BENE_LAST_NAME like '%-%' then
right(BENE_LAST_NAME, LEN(BENE_LAST_NAME) -CHARINDEX('-', BENE_LAST_NAME))
else BENE_LAST_NAME
end,
...
我认为您可以大大简化您的代码。下面考虑一个不同但具有代表性的样本数据
with data (name) as
(select 'first-last' union select 'first last' union select 'firstlast'),
data_prepped (name, indx) as
(select name,coalesce(nullif(charindex(' ', name)+charindex('-', name),0),len(name))
from data)
select name,
left(name, indx-1) as part1,
right(name, indx) as part2
from data_prepped