sql - 将列中的值与 SSMS 中的不同段或列分开

标签 sql sql-server

我有一张 table TABLE1如下 :

YEAR    |  GL_CODE
-------------------------------------------
2019    |  141.0000.1001.732155.0000.000.0000.
2019    |  141.0000.0000.143402.0000.131.0000.
2019    |  541.000.00.00.00.149104.0000.000.00
2019    |  541.101.04.00.00.731104.0000.000.00
2019    |  141.0000.0000.151310.0000.000.0000.
2019    |  541.102.06.00.16.714101.7098.000.00
2019    |  111.00000.0511.766701.0000.000.0000
2019    |  111.00000.0512.520111.5003.331.0000

我需要将它分成不同的段或列,如下所示:
YEAR    |SEGMENT1|SEGMENT2|SEGMENT3|SEGMENT4|SEGMENT5|SEGMENT6|SEGMENT7 |SEGMENT8|SEGMENT9
------------------------------------------------------------------------------------------
2019    |  141   |  0000  | 1001   |732155  | 0000   | 000    | 0000    | NULL   | NULL
2019    |  141   |  0000  | 0000   |143402  | 0000   | 131    | 0000    | NULL   | NULL
2019    |  541   |  000   | 00     | 00     | 00     |149104  | 0000    | 000    | 00
2019    |  541   |  101   | 04     | 00     | 00     |731104  | 0000    | 000    | 00
2019    |  141   |  0000  | 0000   |151310  | 0000   | 000    | 0000    | NULL   | NULL
2019    |  541   |  102   | 06     | 00     |714101  |714101  | 7098    | 000    | 00
2019    |  111   | 00000  | 0511   |766701  | 0000   | 000    | 0000    | NULL   | NULL
2019    |  111   | 00000  | 0512   |520111  | 5003   | 331    | 0000    | NULL   | NULL

请注意,所有条目都没有固定数量的段。

我尝试使用:
select YEAR,PERIOD,SUBSTRING(GL_CODE,1,3) as segment1,
SUBSTRING(GL_CODE,
          charindex('.', GL_CODE, 1)+1,
          ((charindex('.',GL_CODE, (charindex('.', GL_CODE, 1)+1))+1)-(charindex('.', GL_CODE, 1)+1)-1)
          ) as segment2,  
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE, (charindex('.', GL_CODE, 1)+1))+1,
          (charindex('.',GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1)-
               (charindex('.',GL_CODE, (  charindex('.', GL_CODE, 1)+1))+1)-1
          ) as segment3,  
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1,
          (charindex('.',GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1 )-(charindex('.',GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1)-1
          ) as segment4,
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1,(charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.',GL_CODE, 1)+1))+1))+1))+1))+1)-(charindex('.',GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1)-1
          ) as segment5,
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, 
               (charindex('.',GL_CODE, 1)+1))+1))+1))+1))+1,
          (charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, 
              (charindex('.',    GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1)
                -(charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.',GL_CODE, 1)+1))+1))+1))+1))+1)-1
          ) as segment6,
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, 
              (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1,
          (charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,
              (charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1))+1)
                -(charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1)-1
          ) as segment7,
SUBSTRING(GL_CODE,
          charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,
              (charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1))+1,
          (charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,
              (charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE,
              (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1))+1))+1)
                -(charindex('.',GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,(charindex('.', GL_CODE,
              (charindex('.', GL_CODE, (charindex('.', GL_CODE, (charindex('.', GL_CODE, 1)+1))+1))+1))+1))+1))+1))+1)-1
          ) as segment8
from TABLE1;

我正在将值提高到第 6 段...在第 6 段之后我收到错误。
任何人都可以建议更改代码或替代方法吗?

提前致谢

阿克谢

最佳答案

创建 UDF(用户定义函数)

 CREATE FUNCTION dbo.fn_Split
(   
    @str varchar(max),
    @delim char(1), 
    @columnCnt int = 50
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT * 
    FROM (SELECT 
            nn = (nn - 1) / @columnCnt + 1, 
            nnn = 'value' + cast(((nn - 1) % @columnCnt) + 1 as varchar(10)), 
            value
        FROM (SELECT 
            nn = ROW_NUMBER() over (order by (select null)),
            value
            FROM string_split(@str, @delim) aa
            ) aa
        where nn > 0
    ) bb
    PIVOT  
    (  
    max(value) 
    FOR nnn IN (    
        value1, value2, value3, value4, value5, value6, value7, value8, value9  
     )  
    ) AS PivotTable 
)

然后在查询中使用该函数
CREATE TABLE #TBL ([YEAR] INT, GL_CODE VARCHAR(300))
INSERT INTO #TBL VALUES
(2019,'141.0000.1001.732155.0000.000.0000.'),
(2019,'141.0000.0000.143402.0000.131.0000.'),
(2019,'541.000.00.00.00.149104.0000.000.00'),
(2019,'541.101.04.00.00.731104.0000.000.00'),
(2019,'141.0000.0000.151310.0000.000.0000.'),
(2019,'541.102.06.00.16.714101.7098.000.00'),
(2019,'111.00000.0511.766701.0000.000.0000'),
(2019,'111.00000.0512.520111.5003.331.0000');

 SELECT 
[YEAR],
f.*
 FROM  #TBL 
 cross apply dbo.fn_Split(#TBL.GL_CODE, '.', DEFAULT) as f

输出

enter image description here

您可以将列名称更改为您的名称

关于sql - 将列中的值与 SSMS 中的不同段或列分开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60089627/

相关文章:

sql - 计算 group by 中具有最大值的行

sql - oracle 中的 DATE/TIME - 日期持续时间函数

sql - 报表中的每一列都由单独的独立查询派生

sql - SQL中临时表与物理表的比较速度是多少?

sql-server - 在同一 Amazon RDS 上创建重复的 SQL Server 数据库

c# - 为什么 Find 方法生成 TOP(2) 查询?

mysql - 如何检查两个不同表中是否存在两列数据? MySQL

sql - T-SQL 输出插入子句 - 访问不在插入/删除表中的数据

sql - 获取尚未分配给成员查询的角色

sql-server - 日期 SELECT 不返回所有可用值