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

时间:2014-06-23 11:39:14

标签: 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\MyOptionl\AO_Amendment_2 August 2013.docx

我创建了从Col1Col10

的列

我想用分隔符'\'

分隔每个值

我们的想法是每栏都有:

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

W:  2-Work  ALBO  00_Proposal ALxO_Amendement #1_20091022_signed.pdf

我知道如何使用charindexsubstring,但每行(8500行)的'\'数量不同。

你能帮帮我吗?

我正在使用Microsoft SQL Server 2012。

非常感谢

编辑2014/06/24

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

实际上,这是我的想法:

1 - 识别临时表中的所有ID以进行循环

- 关于déclareune table tempo 声明@IdTable表( id int, src nvarchar(max))

- 在injecte tous les id existant de la table 插入@IdTable(id,src) 从albo中选择id,src

- 关于déclarel'iddedébuten commencant par le plus petit 声明@id int =(从ALBO中选择min(id))

- 继续la boucle的Tnat qu'il reste des ID 而@id不为空 开始

打印@id 从@IdTable中选择@id = min(id),其中ID> @ID 结束 --Fin de la boucle des ID

2 - 拆分每一行并更新列(Colx =>之前已创建Clolumns) 这段代码应该放在我之前的循环中。

声明@products varchar(max)='W:\ 2-Work \ ALBO \ 13_WP报告\ 13_07_Monthly报告\ 13_07_01 Archives \ 2012 \ 201211 \ Draft \ ALBO-MR-201211 \ gp_scripts \ v1 \ Top10_duree_final.txt' 声明@individual varchar(max)= null

WHILE LEN(@products)> 0 开始     IF PATINDEX('%\%',@ products)> 0     开始         SET @individual = SUBSTRING(@ product,0,PATINDEX('%\%',@ products))         选择@individual --i必须使用ID

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

END

3 个答案:

答案 0 :(得分:0)

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

无论如何,这将满足您的要求(甚至可能是您想要的):

-- 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

答案 1 :(得分:0)

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

[另外,由于某种原因,下面代码的颜色显示为奇数,因此将其复制并粘贴到您的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

您可能更喜欢将每个文件夹放在自己的行上,如果是这样,请使用以下查询替换上面的数据透视部分

select  item
      , subitem
      , location
      , split from Path_Expanded where item = 16

答案 2 :(得分:0)

单向(去骗):

;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