TSQL - 将分隔的字符串拆分为列
TSQL - Split delimited String into columns
问题
我有许多文件名字符串,我想使用波浪字符作为分隔符将其解析为列。字符串采用静态格式:
- 文件路径示例
C:\My Documents\PDF
- 姓例子
Walker
- 名字示例
Thomas
- 出生日期 例子
19991226
- 文档创建日期时间示例
20180416150322
- 文档扩展名 示例
.pdf
因此,完整的串联示例如下:
C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf
我想忽略字符串中给出的文件路径和扩展名,只将以下值解析到列中:
- 姓氏、名字、出生日期、文档创建日期时间
所以像这样:
SELECT Surname = --delimitedString[0]
FirstName = --delimitedString[1]
--etc.
我试过的
我知道我需要执行几项任务才能拆分字符串,首先我需要 trim 关闭扩展名和文件路径,以便我可以 return由波浪线 (~) 分隔的字符串。
这对我来说是第一个问题,但是问题 2 是拆分新的分隔字符串本身,即
Walker~Thomas~19991226~20180416150322
我已经很好地阅读了这篇非常全面的 question 并且似乎(因为我使用 SQL Server 2008R2)唯一的选择是使用带循环的函数或递归 CTE 或尝试使用 SUBSTRING()
和 charIndex()
.
的非常混乱的尝试
我知道如果我可以访问 SQL Server 2016,我可以使用 string_split
但不幸的是我无法升级。
我确实可以访问 SSIS,但我对它还很陌生,所以决定尝试在 SQL 语句
中完成大部分工作
我知道你提到过想尽可能避免使用 charindex()
选项,但我以一种半可读的方式解决了这个问题。当我 space 每个参数在不同的行上并使用缩进级别时,我发现像这样阅读复杂的函数有点容易。这不是最合适的外观,但它有助于提高易读性:
with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)
select
substring(
filepath,
len(filepath)-charindex('\',reverse(filepath))+2, --start location, after last '\'
len(filepath)- --length of path
(len(filepath)-charindex('\',reverse(filepath))+2)- --less characters up to last '\'
(len(filepath)-charindex('.',filepath)) --less file extention
)
from string
这里有一个没有分离器的方法应该不会太复杂...
declare @var table (filepath varchar(256))
insert into @var values
('C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf')
;with string as(
select
x = right(filepath,charindex('\',reverse(filepath))-1)
from @var
)
select
SurName= substring(x,1,charindex('~',x) - 1)
,FirstName = substring(x,charindex('~',x) + 1,charindex('~',x) - 1)
from string
Fritz 已经有了一个很好的开始,我的回答只是补充一下
with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)
, newstr as (
select
REPLACE(substring(
filepath,
len(filepath)-charindex('\',reverse(filepath))+2, --start location, after last '\'
len(filepath)- --length of path
(len(filepath)-charindex('\',reverse(filepath))+2)- --less characters up to last '\'
(len(filepath)-charindex('.',filepath)) --less file extention
) , '~', '.') as new_part
from string
)
SELECT
PARSENAME(new_part,4) as Surname,
PARSENAME(new_part,3) as [First Name],
PARSENAME(new_part,2) as [Birth Date],
PARSENAME(new_part,1) as [Document Created Datetime]
FROM newstr
问题
我有许多文件名字符串,我想使用波浪字符作为分隔符将其解析为列。字符串采用静态格式:
- 文件路径示例
C:\My Documents\PDF
- 姓例子
Walker
- 名字示例
Thomas
- 出生日期 例子
19991226
- 文档创建日期时间示例
20180416150322
- 文档扩展名 示例
.pdf
因此,完整的串联示例如下:
C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf
我想忽略字符串中给出的文件路径和扩展名,只将以下值解析到列中:
- 姓氏、名字、出生日期、文档创建日期时间
所以像这样:
SELECT Surname = --delimitedString[0]
FirstName = --delimitedString[1]
--etc.
我试过的
我知道我需要执行几项任务才能拆分字符串,首先我需要 trim 关闭扩展名和文件路径,以便我可以 return由波浪线 (~) 分隔的字符串。
这对我来说是第一个问题,但是问题 2 是拆分新的分隔字符串本身,即
Walker~Thomas~19991226~20180416150322
我已经很好地阅读了这篇非常全面的 question 并且似乎(因为我使用 SQL Server 2008R2)唯一的选择是使用带循环的函数或递归 CTE 或尝试使用 SUBSTRING()
和 charIndex()
.
我知道如果我可以访问 SQL Server 2016,我可以使用 string_split
但不幸的是我无法升级。
我确实可以访问 SSIS,但我对它还很陌生,所以决定尝试在 SQL 语句
中完成大部分工作我知道你提到过想尽可能避免使用 charindex()
选项,但我以一种半可读的方式解决了这个问题。当我 space 每个参数在不同的行上并使用缩进级别时,我发现像这样阅读复杂的函数有点容易。这不是最合适的外观,但它有助于提高易读性:
with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)
select
substring(
filepath,
len(filepath)-charindex('\',reverse(filepath))+2, --start location, after last '\'
len(filepath)- --length of path
(len(filepath)-charindex('\',reverse(filepath))+2)- --less characters up to last '\'
(len(filepath)-charindex('.',filepath)) --less file extention
)
from string
这里有一个没有分离器的方法应该不会太复杂...
declare @var table (filepath varchar(256))
insert into @var values
('C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf')
;with string as(
select
x = right(filepath,charindex('\',reverse(filepath))-1)
from @var
)
select
SurName= substring(x,1,charindex('~',x) - 1)
,FirstName = substring(x,charindex('~',x) + 1,charindex('~',x) - 1)
from string
Fritz 已经有了一个很好的开始,我的回答只是补充一下
with string as (select 'C:\My Documents\PDF\Walker~Thomas~19991226~20180416150322.pdf' as filepath)
, newstr as (
select
REPLACE(substring(
filepath,
len(filepath)-charindex('\',reverse(filepath))+2, --start location, after last '\'
len(filepath)- --length of path
(len(filepath)-charindex('\',reverse(filepath))+2)- --less characters up to last '\'
(len(filepath)-charindex('.',filepath)) --less file extention
) , '~', '.') as new_part
from string
)
SELECT
PARSENAME(new_part,4) as Surname,
PARSENAME(new_part,3) as [First Name],
PARSENAME(new_part,2) as [Birth Date],
PARSENAME(new_part,1) as [Document Created Datetime]
FROM newstr