拆分 SQL 列

Splitting SQL column

我有一个 SQL 列需要拆分。一些列(列名是城市)的值是:芝加哥 (0078)、西雅图 (02136)、奥马哈 (008721),它们需要拆分为

City: Chicago, Seattle, Omaha. 
MU: 0078, 02136, 008721

我不确定 SQL 是否有用于此目的的内置函数,还是我应该使用变量?

STRING_SPLIT() 仅在 SQL SERVER 2016 及更高版本中受支持,因此您可以使用以下替代方法来获得所需的拆分输出:

SELECT 
LEFT ( City , CHARINDEX ( '(' , City , 0 )- 2) as CityName,
REPLACE(RIGHT( City , LEN(City) - CHARINDEX ( '(' , City , 0 )), ')' , '') as MU 
FROM TABLENAME

好吧,这不是很好,但它似乎工作。结合 UDF(在下面列出)

Declare @Table table (CityString varchar(100),NewCityString 

varchar(100),NewZipString varchar(100))
    Insert into @Table values
    ('Chicago (0078), Seattle (02136), Omaha (008721)',null,null)


Update @Table Set 
       NewCityString = Replace(ltrim(rtrim(Replace((Select Isnull(Substring(Pos1,1,CharIndex('(',Pos1)-1),'')
                              +IIf(Pos2 is null,'',', ')
                              +Isnull(Substring(Pos2,1,CharIndex('(',Pos2)-1) ,'')
                              +IIf(Pos3 is null,'',', ')
                              +Isnull(Substring(Pos3,1,CharIndex('(',Pos3)-1) ,'')
                              +IIf(Pos4 is null,'',', ')
                              +Isnull(Substring(Pos4,1,CharIndex('(',Pos4)-1),'')
                              +IIf(Pos5 is null,'',', ')
                              +IsNull(Substring(Pos5,1,CharIndex('(',Pos5)-1) ,'')
                              +IIf(Pos6 is null,'',', ')
                              +IsNull(Substring(Pos6,1,CharIndex('(',Pos6)-1) ,'')
                              +IIf(Pos7 is null,'',', ')
                              +IsNull(Substring(Pos7,1,CharIndex('(',Pos7)-1) ,'')
                              +IIf(Pos8 is null,'',', ')
                              +IsNull(Substring(Pos8,1,CharIndex('(',Pos8)-1) ,'')
                              +IIf(Pos9 is null,'',', ')
                              +IsNull(Substring(Pos9,1,CharIndex('(',Pos9)-1) ,'')
                         From [dbo].[udf-Str-Parse-Row](CityString,',')),' , ',', '))),'  ',' ')+'.'
      ,NewZipString = 'MU: '+ltrim(rtrim((Select Replace(Isnull(Substring(Pos1,CharIndex('(',Pos1)+1,25),''),')','')
                              +IIf(Pos2 is null,'',', ')
                              +Replace(Isnull(Substring(Pos2,CharIndex('(',Pos2)+1,25),''),')','')
                              +IIf(Pos3 is null,'',', ')
                              +Replace(Isnull(Substring(Pos3,CharIndex('(',Pos3)+1,25),''),')','')
                              +IIf(Pos4 is null,'',', ')
                              +Replace(Isnull(Substring(Pos4,CharIndex('(',Pos4)+1,25),''),')','')
                              +IIf(Pos5 is null,'',', ')
                              +Replace(Isnull(Substring(Pos5,CharIndex('(',Pos5)+1,25),''),')','')
                              +IIf(Pos6 is null,'',', ')
                              +Replace(Isnull(Substring(Pos6,CharIndex('(',Pos6)+1,25),''),')','')
                              +IIf(Pos7 is null,'',', ')
                              +Replace(Isnull(Substring(Pos7,CharIndex('(',Pos7)+1,25),''),')','')
                              +IIf(Pos8 is null,'',', ')
                              +Replace(Isnull(Substring(Pos8,CharIndex('(',Pos8)+1,25),''),')','')
                              +IIf(Pos9 is null,'',', ')
                              +Replace(Isnull(Substring(Pos9,CharIndex('(',Pos9)+1,25),''),')','')
                         From [dbo].[udf-Str-Parse-Row](CityString,','))))



Select * from @Table

Returns

CityString                                         NewCityString                NewZipString
Chicago (0078), Seattle (02136), Omaha (008721)    Chicago, Seattle, Omaha.     MU: 0078, 02136, 008721

UDF -- 我目前有 9 个的限制,但您可以轻松添加更多

CREATE FUNCTION [dbo].[udf-Str-Parse-Row] (@String varchar(max),@Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',')
--       Select * from [dbo].[udf-Str-Parse-Row]('John Cappelletti',' ')
--       Select * from [dbo].[udf-Str-Parse-Row]('id26,id46|id658,id967','|')

Returns Table 

As

Return (
    SELECT Pos1 = xDim.value('/x[1]','varchar(250)')
          ,Pos2 = xDim.value('/x[2]','varchar(250)')
          ,Pos3 = xDim.value('/x[3]','varchar(250)')
          ,Pos4 = xDim.value('/x[4]','varchar(250)')
          ,Pos5 = xDim.value('/x[5]','varchar(250)')
          ,Pos6 = xDim.value('/x[6]','varchar(250)')
          ,Pos7 = xDim.value('/x[7]','varchar(250)')
          ,Pos8 = xDim.value('/x[8]','varchar(250)')
          ,Pos9 = xDim.value('/x[9]','varchar(250)')
    FROM (Select Cast('<x>' + Replace(@String,@Delimeter,'</x><x>')+'</x>' as XML) as xDim) A
)

有更优雅的解决方案适用于 MS SQL Server 2005+。

declare @s varchar(100)='Chicago (0078), Seattle (02136), Omaha (008721)'

;with cities as (--need CTE to have valid xml 
--build xml string
select cast('<cities><city><name>'+replace(
                         replace(
                                replace(@s,')','</id>'),
                        '(','</name><id>'),',','</city><city><name>')
            +'</city></cities>' as xml) x
)
--and tabulate xml
select t.v.value('./id[1]','varchar(10)') id,
rtrim(ltrim(t.v.value('./name[1]','varchar(20)'))) city --remove spaces
from cities cross apply cities.x.nodes('cities/city') t(v)

以防万一,XML 由 CTE 创建。

<cities>
  <city>
    <name>Chicago </name>
    <id>0078</id>
  </city>
  <city>
    <name> Seattle </name>
    <id>02136</id>
  </city>
  <city>
    <name> Omaha </name>
    <id>008721</id>
  </city>
</cities>