向左走;在线可选字符的右侧

时间:2013-04-29 14:09:33

标签: sql sql-server sql-server-2008 tsql split

我有以下不同类型的输入nvarchar值:

  • FirstName|LastName
  • FirstName
  • |LastName

我需要在我的SQL脚本中输出FirstNameLastName作为单独的列。

SELECT FLname as Original
    ,SUBSTRING(FLname, 0, ISNULL(NULLIF(CHARINDEX('|', FLname),0), LEN(FLname)+1)) as FirstName
    ,SUBSTRING(FLname, ISNULL(NULLIF(CHARINDEX('|', FLname)+1,1), LEN(FLname)+1), LEN(FLname)+1) as LastName

这个逻辑可行,但我发现它不可读,特别是对于未来的开发人员而言。

我知道我可以创建一个用户定义函数来存储这个逻辑,但我宁愿避免添加它。

是否有一种更简洁的方法可以作为内联SQL语句实现所需的结果?

2 个答案:

答案 0 :(得分:0)

我就是这样做的:(更正)

;WITH cte As
(
    SELECT *,CHARINDEX('|', FLname) As PipeOffset
    FROM yourTable
)
SELECT
    FLname As Original,
    CASE When PipeOffset = 0 Then FLname
         When PipeOffset > 1 Then LEFT(FLname, PipeOffset-1)
         ELSE NULL  END     As FirstName,
    CASE When >0 And < LEN(FLname) 
         Then RIGHT(FLname, LEN(FLname)- PipeOffset)
         ELSE NULL  END     As LastName
FROM cte

答案 1 :(得分:0)

这与@ RBarryYoung使用CTE获得CHARINDEXLEFTRIGHT功能的清晰可读性的答案非常类似。如果需要,可以将空字符串('')替换为null。

FIDDLE DEMO

;with cte as (
  select FLname, charindex('|',FLname) divider
  from t
)
select FLname original, 
       case when divider = 1 then ''
            when divider > 1 then left(FLname, divider-1) 
       else FLname end firstName,
       case when divider > 0 then right(FLname, len(FLname)-divider)
            else '' end lastName
from cte

|           ORIGINAL | FIRSTNAME | LASTNAME |
---------------------------------------------
| FirstName|LastName | FirstName | LastName |
|          FirstName | FirstName |          |
|          |LastName |           | LastName |