Sql 在列中拆分字符串并在列中添加值

Sql 在列中拆分字符串并在列中添加值,sql,tsql,sql-server-2012,Sql,Tsql,Sql Server 2012,我有一个表,其中有几行数据,如下所示: 16 W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf 17 W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx 18 W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx 19 W:\2-Work\ALBO\MyOption

我有一个表,其中有几行数据,如下所示:

16  W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf
17  W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx
18  W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx
19  W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx
我已经创建了从Col1到Col10的列

我想用分隔符“\”分隔每个值

我们的想法是在每一列上都有:

Col1 | Col2 | Col3 | Col4 | Col5 |etc...

W:  2-Work  ALBO  00_Proposal ALxO_Amendement #1_20091022_signed.pdf
我知道如何使用charindex和substring,但每行8500行上的“\”数不同

你能帮我吗

我正在使用Microsoft SQL Server 2012

多谢各位

编辑2014/06/24

我的目标是生成完整路径和分割路径的XML

实际上,我的想法是:

1-标识临时表to do循环中的所有ID

-论déclare的桌上节奏 声明@IdTable表格 id int, src nvarcharmax

-关于使用les-id-existant-de-la表的内射 插入@IdTable id,src 从albo中选择id、src

——克莱尔·D·D·D·E·D·P·P·Plt 声明@id int=select minid from ALBO

-你可以继续走下去 而@id不为空 开始

打印@id 从@IdTable中选择@id=minid,其中id>@id 终止 -鱼翅

2-拆分每行并更新列Colx=>之前已经创建了克隆 这段代码应该放在我前面的循环中

声明@products varcharmax='W:\2-Work\ALBO\13\U WP Reporting\13\U 07\U Monthly reports\13\U 07\U 01 Archives\2012\201211\Draft\ALBO-MR-201211\gp\U scripts\v1\Top10\U duree\U final.txt' 声明@individual varcharmax=null

当LEN@products > 0 开始 如果PATINDEX“%\%”,@products>0 开始 设置@个人=SUBSTRING@products,0,PATINDEX“%\%”,@products 选择@individual-我必须使用ID进行创建和更新

    SET @products = SUBSTRING(@products, LEN(@individual + '\') + 1,
                                                 LEN(@products))
END
ELSE
BEGIN
    SET @individual = @products
    SET @products = NULL
    print @individual
END

结束

以下查询将获得您要查找的内容;正如其他人所指出的,这不是一个特别好的设计。例如,当您查找文件名时,每次都在不同的列中,会发生什么情况

无论如何,这将满足您的要求,甚至满足您的要求:

-- Test Data
CREATE TABLE #FilePath (FileNumber INT IDENTITY(1,1), FilePath VARCHAR(1000))
INSERT INTO #FilePath (FilePath) 
SELECT 'W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf' UNION
SELECT 'W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx' UNION
SELECT 'W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx' UNION
SELECT 'W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx'
GO

-- Numbers CTE
WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 1000 -- set this to the maximum length of your file path
)

SELECT 
    FilePath,
    [1] AS Col1,
    [2] AS Col2,
    [3] AS Col3,
    [4] AS Col4,
    [5] AS Col5,
    [6] AS Col6,
    [7] AS Col7,
    [8] AS Col8,
    [9] AS Col9,
    [10] AS Col10
FROM 
  (
    SELECT 
        FilePath, 
        ROW_NUMBER() OVER (PARTITION BY FilePath ORDER BY n) RowNum,
        CAST(LTRIM(RTRIM(NULLIF(SUBSTRING('\' + FilePath + '\' , n , CHARINDEX('\' ,     '\' + FilePath + '\' , n) - n) , ''))) AS VARCHAR(1000)) FolderName
    FROM Numbers, #FilePath
    WHERE 
        n <= Len('\' + FilePath + '\') AND SubString('\' + FilePath + '\' , n - 1, 1) = '\' AND 
        CharIndex('\' , '\' + FilePath+ '\' , n) - n > 0
  )P
PIVOT 
   (MAX(FolderName) FOR RowNum IN 
    ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])
    ) UP
OPTION (MAXRECURSION 1000)-- set this to the maximum length of your file path


-- Clean up
DROP TABLE #FilePath

正如其他人所说,这可能不是做事情的最佳方式,如果你解释你将用结果做什么,它可能会帮助我们提供更好的选择

[此外,由于某些原因,下面代码的颜色显示为奇数,因此请将其复制并粘贴到Sql server中,以便更好地查看它]

drop table #Path

create table #Path (item bigint,location varchar(1000))

insert into #Path 
select 16  ,'W:\2-Work\ALBO\00_Proposal\ALxO_Amendement #1_20091022_signed.pdf' union
select 17  ,'W:\2-Work\ALBO\00_Proposal\Level1\ALBO_Amendment #1_20110418.docx' union
select 18  ,'W:\2-Work\ALBO\00_Proposal\A\BR\T\X_#1_20110418_final.docx' union
select 19  ,'W:\2-Work\ALBO\MyOptionl\AO_Amendment_2 August 2013.docx'


select * from #Path;


with Path_Expanded(item,subitem,location, start, ending, split)
as(
select item
     , 1 --subitem begins at 1
     , location -- full location path
     , 0 --start searching the file from the 0 position
     , charindex('\',location) -- find the 1st '\' charactor
     , substring(location,0,charindex('\',location)) --return the string from the start position, 0, to the 1st '\' charactor

from #Path
union all
select item
     , subitem+1 --add 1 to subitem
     , location -- full location path
     , ending+1 -- start searching the file from the position after the last '\' charactor
     , charindex('\',location,ending+1)-- find the 1st '\' charactor that occurs after the last '\' charactor found
     , case when charindex('\',location,ending+1) = 0 then substring(location,ending+1,1000) --if you cant find anymore '\', return everything else after the last '\'
            else substring(location,ending+1, case when charindex('\',location,ending+1)-(ending+1) <= 0 then 0 
            else charindex('\',location,ending+1)-(ending+1) end )--returns the string between the last '\' charactor and the next '\' charactor
            end 

from Path_Expanded
where ending > 0 --stop once you can't find anymore '\' charactors
)


--pivots the results 
select item
    , max(case when subitem = 1 then split else '' end) as col1
    , max(case when subitem = 2 then split else '' end) as col2
    , max(case when subitem = 3 then split else '' end) as col3
    , max(case when subitem = 4 then split else '' end) as col4
    , max(case when subitem = 5 then split else '' end) as col5
    , max(case when subitem = 6 then split else '' end) as col6
    , max(case when subitem = 7 then split else '' end) as col7
    , max(case when subitem = 8 then split else '' end) as col8
    , max(case when subitem = 9 then split else '' end) as col9
    , max(case when subitem = 10 then split else '' end) as col10

from Path_Expanded
group by item
单向重复数据消除:

;with T(ordinal, path, starts, pos) as (
    select 1, path, 1, charindex('\', path) from #tbl
    union all
    select ordinal + 1, path, pos + 1, charindex('\', path, pos + 1)
    from t where pos > 0
)
select [1],[2],[3],[4],[5],[6],[7],[8],[9],[10] from (
    select 
        ordinal, path, substring(path, starts, case when pos > 0 then pos - starts else len(path) end) token
    from T
) T2
pivot (max(token) for ordinal in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) T3

那张桌子不好,德斯金。您想做什么?您可以创建一个函数,将数据按\拆分,并为每行返回一个表,然后使用拆分函数的insert语句将表插入col1到col10中。尝试编写代码来实现上述功能,以防您遇到我们这里的问题!:您不只是将“\”替换为“”?我想将行“分解”并将“Col1”更新为“Col10”,例如:“This\Is\My\句子”=>Col1:This | Col2:Is | Col3:My | Col4:Sentence您试图解决的真正问题是什么?为什么您认为创建10个任意列是解决此问题的方法?事实并非如此。如果您试图收集有关文件夹的统计信息,还有其他方法可以做到这一点。我的目标是创建一个XML宽度,以“分解”所有信息,并保留原始路径。
;with T(ordinal, path, starts, pos) as (
    select 1, path, 1, charindex('\', path) from #tbl
    union all
    select ordinal + 1, path, pos + 1, charindex('\', path, pos + 1)
    from t where pos > 0
)
select [1],[2],[3],[4],[5],[6],[7],[8],[9],[10] from (
    select 
        ordinal, path, substring(path, starts, case when pos > 0 then pos - starts else len(path) end) token
    from T
) T2
pivot (max(token) for ordinal in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) T3