Sql server 使用Substring&patindex将字符串的一部分提取到新的MS SQL列中

Sql server 使用Substring&patindex将字符串的一部分提取到新的MS SQL列中,sql-server,Sql Server,我在MS SQL中有一个字段,它是这样连接的:TopLevel>Middlevel>Lowestlevel,字符串的长度不同。有时字符串较短,只有topLevel或topLevel>MidLevel 我需要做的是在>处拆分字符串,并将中间的文本放入新的列/字段中。 我尝试了parsename,它非常有效,直到长度开始改变 我所拥有的不会出错,但也不会生成任何内容-除了3个空列 SELECT [program_Name] ,substring([Program_Name],1, patinde

我在MS SQL中有一个字段,它是这样连接的:TopLevel>Middlevel>Lowestlevel,字符串的长度不同。有时字符串较短,只有topLevel或topLevel>MidLevel 我需要做的是在>处拆分字符串,并将中间的文本放入新的列/字段中。 我尝试了parsename,它非常有效,直到长度开始改变

我所拥有的不会出错,但也不会生成任何内容-除了3个空列

SELECT 
[program_Name]

,substring([Program_Name],1, patindex([Program_Name], '>')) as UP
,substring([Program_Name],patindex([Program_Name], '>*>') - patindex([Program_Name], '>'), patindex([Program_Name], '>*>')) as MID
,substring([Program_Name],patindex([Program_Name], '>*>*>') - patindex([Program_Name], '>*>'), patindex([Program_Name], '>*>')) as LOW


 */
  FROM [dbo].[MSP_EpmProject_UserView]
只要数据本身不包含,就使用PARSENAME.:

输出:

╔══════════╦══════════╦═════════════╗
║    UP    ║   MID    ║     LOW     ║
╠══════════╬══════════╬═════════════╣
║ TopLevel ║ MidLevel ║ Lowestlevel ║
╚══════════╩══════════╩═════════════╝
备注:

使用PARSENAME,您最多可以获得4个级别 PARSENAME与SYSNAME一起使用,SYSNAME是NVARCHAR128的别名 如果您有TOP.DATA>MID.DATA>LOW.DATA,您可以先更改。到^,然后>到。在最后,我再一次来到这里。 编辑:

使用PARSENAME有点老套,所以让我们用老办法:

CREATE TABLE #tab(col NVARCHAR(1000));
INSERT INTO #tab(col) VALUES( 'TOP>MID>LOW'), ('A>B>C>D');

WITH tally AS
(
SELECT TOP 5000 rn = ROW_NUMBER() OVER(ORDER BY (SELECT 1))
  FROM master..spt_values
), cte AS
( SELECT col, s.val, pos
  FROM #tab t
  CROSS APPLY(
    SELECT SUBSTRING('>' + t.col + '>', rn + 1,
           CHARINDEX('>', '>' + t.col + '>', rn + 1) - rn -1)AS VAL,
           pos = ROW_NUMBER() OVER (ORDER BY rn)
    FROM tally
    WHERE rn <= LEN('>' + t.col + '>') - 1
      AND SUBSTRING('>' + t.col + '>', rn, 1) = '>') AS s(val, pos)
)
SELECT col, [1] AS UP, [2] AS MID, [3] AS LOW
FROM cte
PIVOT (MAX(val) FOR pos IN ([1],[2],[3],[4],[5])) AS pvt;
现在您可以拥有更多级别,只需添加[4]、[5]、。。。选择列列表等


请提供一些示例数据和所需输出,以便我们可以帮助您。我使用ParseName时遇到的问题是长度不同。所以有时候我会有这样的文件:IT>CTO>Project,IT为顶部,CTO为中间,Proejct为底部,有时候IT为顶部,Proejct为底部,但它被放在底部。以及任意数量的Other组合。我不知道如何使用Parsename将其设置为顶部或IT>Security设置为顶部和中间。应该注意的是,Parsename的第一个参数是sysname。对于SQL Server 2008 R2+而言,这相当于NVARCHR128,如果列大于该值,则可能不足以满足要求。这将起作用,但很难强制使用设计用于使不同功能发挥作用的函数。“这并不是一件坏事,只是需要小心对待。”胡安卡洛索佩萨好的,我会发帖的CTE@lad2025抱歉,我不是说你错了,我只是提供了链接,以便OP可以检查功能。@JuanCarlosOropeza请检查我的更新,以了解完整性:
CREATE TABLE #tab(col NVARCHAR(1000));
INSERT INTO #tab(col) VALUES( 'TOP>MID>LOW'), ('A>B>C>D');

WITH tally AS
(
SELECT TOP 5000 rn = ROW_NUMBER() OVER(ORDER BY (SELECT 1))
  FROM master..spt_values
), cte AS
( SELECT col, s.val, pos
  FROM #tab t
  CROSS APPLY(
    SELECT SUBSTRING('>' + t.col + '>', rn + 1,
           CHARINDEX('>', '>' + t.col + '>', rn + 1) - rn -1)AS VAL,
           pos = ROW_NUMBER() OVER (ORDER BY rn)
    FROM tally
    WHERE rn <= LEN('>' + t.col + '>') - 1
      AND SUBSTRING('>' + t.col + '>', rn, 1) = '>') AS s(val, pos)
)
SELECT col, [1] AS UP, [2] AS MID, [3] AS LOW
FROM cte
PIVOT (MAX(val) FOR pos IN ([1],[2],[3],[4],[5])) AS pvt;