【问题标题】:parsing first and last names from sql table从 sql 表中解析名字和姓氏
【发布时间】:2017-01-30 21:16:09
【问题描述】:

我的 SQL Server 2008 数据库中有一个包含 c/o Full Name 的列。我在区分名字和姓氏时遇到问题。我在自己的列中有 c/o,但我需要名字/姓氏。我知道第二个和第三个 case 语句存在问题,但我不确定我需要更改什么。我应该将索引变量存储在某处以引用它们吗?

Declare @t table ( [name] varchar(100) )

INSERT INTO @t ( Name )
SELECT Street1 FROM tblPeople
WHERE CO = 'Y' AND LastName NOT LIKE 'SUMMERHAVEN INC' AND Street1 Like '%c/o%'

SELECT
    [name],
    CHARINDEX(' ', [name]),
    CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
        LEFT([name],CHARINDEX(' ',[name])-1)
    ELSE
        [name]
    END as CO,
    CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
        SUBSTRING([name],CHARINDEX(' ',[name])+1, ( LEN([name]) - CHARINDEX(' ',[name])+1) )
    ELSE
        NULL
    END as FIRST_NAME,
    CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
        SUBSTRING([name],CHARINDEX(' ',[name])+1, ( LEN([name]) - CHARINDEX(' ',[name])+1) )
    ELSE
        NULL
    END as LAST_NAME
FROM @t

【问题讨论】:

  • 看起来像 SQL Server?哪个版本?
  • @HartCO 我在问题中添加了版本,但它是SQL Server 2008。
  • 一些样本数据怎么样?我们没有你的桌子 tblPeople。
  • @SeanLange 一个名字的例子是c/o Sara Schultz

标签: sql sql-server sql-server-2008 parsing


【解决方案1】:

令我惊讶的是,PARSENAME() 于 2008 年推出

考虑以下

Declare @YourTable table (Name varchar(50))
Insert Into @YourTable values 
 ('c/o Cher')
,('c/o John Smith')
,('John Smith')

Select *
      ,FirstName=parsename(replace(ltrim(rtrim(replace(name,'c/o',''))),' ','.'),2)
      ,LastName =parsename(replace(ltrim(rtrim(replace(name,'c/o',''))),' ','.'),1)
 From @YourTable

返回

Name            FirstName   LastName
c/o Cher        NULL        Cher
c/o John Smith  John        Smith
John Smith      John        Smith

【讨论】:

  • @SeanLange 我相信您是前段时间通知我的人。好奇的文档显示 2012+
  • 是的,文档有点奇怪。诸如“显示其他版本”之类的东西只能追溯到 2012 年,但其他项目会更远。然后就像你说的那样,他们会提到仅在 2012+ 中可用,这是错误的。不知道他们为什么要走这条路。
【解决方案2】:

披露:像这样解析数据是个坏主意,但是你去吧:

Declare @t table ( [name] varchar(100) )

insert into @t ( Name ) values ('c/o Full Name')

SELECT
CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
    LEFT([name],CHARINDEX(' ',[name])-1)
ELSE
    [name]
END as CO,
CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
    SUBSTRING([name],CHARINDEX(' ',[name])+1, CHARINDEX(' ',[name]) )
ELSE
    NULL
END as FIRST_NAME,
CASE WHEN CHARINDEX(' ', [name]) > 0 THEN
    SUBSTRING([name],CHARINDEX(' ',[name], CHARINDEX(' ',[name])+1), len([name]))
ELSE
    NULL
END as LAST_NAME
FROM @t

【讨论】:

  • 你能解释一下为什么这样解析数据是个坏主意吗?
  • @kevorski 因为这不是解析数据的可靠方法。如果您有多个名字怎么办?或者用户会留下空格的复杂姓氏?当然,如果您从无法更改的来源获取这些数据,那么您将坚持现有的,这是您最好的选择。
【解决方案3】:

这是一种使用公用表表达式的方法,以便查找要中断的空间的逻辑是合理的自我记录。

Declare @t table ( [name] varchar(100) )

insert into @t ( Name )
select 'one two three'
union select 'a bc def'
union select 'one two'
union select 'one'

;with cte1 as 
(
    select name
    ,charindex(' ', name) FirstSpace
    from @t
)
, cte2 as (
    select name
    , FirstSpace
    ,charindex(' ', name, FirstSpace+1) SecondSpace
    from cte1
)
select name
, FirstSpace
, SecondSpace
, case when FirstSpace=0 then name else substring(name, 1, FirstSpace-1) end Company
, case when SecondSpace=0 then null else substring(name, FirstSpace+1, SecondSpace-FirstSpace-1) end FirstName
, case when SecondSpace=0 or SecondSpace=len(name) then null else substring(name, SecondSpace+1, len(name)-SecondSpace) end LastName
from cte2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-09
    • 2010-09-14
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多