从文件夹路径返回特定目录级别

时间:2018-02-07 12:35:37

标签: sql-server tsql

我想从包含文件夹路径的列的每个结果中提取特定目录级别。以下内容适用于一个结果,但是如何应用相同的字符串斩波,以便将整个返回的集合修剪为所需的文件夹目录。

鉴于

C:\Program Files\Folder1\Lang
C:\Program\Folder2\Lang
G:\Program Files\Folder3\
C:\Program Files\Folder4\Lang

输出

Folder1
Folder2
Folder3
Folder4

尝试

DECLARE @a VARCHAR(MAX)
        ,@b VARCHAR(MAX)
        ,@c VARCHAR(MAX)
SELECT
    @c = t.FolderPath
FROM TABLE t

SET @b = LEFT(@c, CHARINDEX('\', @c))
SET @a = RIGHT(@c, LEN(@c) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SET @b = LEFT(@a, CHARINDEX('\', @a))
SET @a = RIGHT(@a, LEN(@a) - LEN(@b))
SELECT
    LEFT(@b,LEN(@B)-1)
    ,@c

2 个答案:

答案 0 :(得分:1)

尝试这样的事情......

示例数据

Declare @t TABLE (SomePKID INT , FolderLocation VARCHAR(MAX))

INSERT INTO  @t VALUES 
 ( 1 , 'C:\Program & Files\Intel')
,( 2 , 'C:\Program & Files (x86)\IIS')
,( 3 , 'C:\Dell & DELL\Update & Packages\log');

<强>查询

SELECT *
FROM @t t 
    CROSS APPLY 
            (
            SELECT   Replace(
                        RTRIM(LTRIM(Split.a.value('.', 'VARCHAR(100)')))
                        ,'|' , '&') DriveOrDirectory
                 ,  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) LevelOrder
            FROM 
             (
                SELECT Cast ('<X>' 
                            + Replace(Replace(t.FolderLocation, '\', '</X><X>'), '&' , '|') 
                            + '</X>' AS XML) AS Data
              ) AS t CROSS APPLY Data.nodes ('/X') AS Split(a) 
            ) c(DriveOrDirectory, LevelOrder)
WHERE c.LevelOrder = 2

结果集

+----------+--------------------------------------+-----------------------+------------+
| SomePKID |            FolderLocation            |   DriveOrDirectory    | LevelOrder |
+----------+--------------------------------------+-----------------------+------------+
|        1 | C:\Program & Files\Intel             | Program & Files       |          2 |
|        2 | C:\Program & Files (x86)\IIS         | Program & Files (x86) |          2 |
|        3 | C:\Dell & DELL\Update & Packages\log | Dell & DELL           |          2 |
+----------+--------------------------------------+-----------------------+------------+

答案 1 :(得分:0)

您可以使用XML执行此操作:

;WITH MyTable AS (
    SELECT 1 as id, N'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community' as FolderPath
    UNION ALL
    SELECT 2, N'C:\Intel\Logs\'
    UNION ALL
    SELECT 3, N'C:\Windows\Cursors\aero_arrow.cur'
), cte AS(
    SELECT  id,
            CAST('<p>'+REPLACE(FolderPath,'\','</p><p>')+'</p>' as xml) as x
    FROM MyTable
)

SELECT  id,
        t.c.value('.','nvarchar(100)') as [value],
        p.number as [position]
FROM cte c
CROSS JOIN [master]..spt_values p
CROSS APPLY c.x.nodes('/p[position()=sql:column("number")]') as t(c)
WHERE p.[type] = 'p'
ORDER BY id, [position]

输出:

id          value                          position
----------- ------------------------------ -----------
1           C:                             1
1           Program Files (x86)            2
1           Microsoft Visual Studio        3
1           2017                           4
1           Community                      5
2           C:                             1
2           Intel                          2
2           Logs                           3
2                                          4
3           C:                             1
3           Windows                        2
3           Cursors                        3
3           aero_arrow.cur                 4

(13 rows affected)