解析单列表中的列和数据

问题描述 投票:3回答:2

我有一个表@tbl_rawData,在其中我从一个非常动态的文件(没有固定的列位置)中加载数据,因此我只在一个列中加载了整个文件。

我需要获取所需的列以及每列的对应数据。

我对ID表中维护的customernameprodnameregency@tbl_collist列感兴趣,但将来,也许我需要更多列,然后在@tbl_collist中插入更多列名。

declare @tbl_rawData table (fileData varchar(max))
insert into @tbl_rawData 
    (fileData)
values
    ('#Columns: ID|customername|addresss|agency|prodname|valuation|regency|ceptam|agan|yaha|citr'),
    ('11|jeev|a-161 kv|criu|uio|1800000|abap|yes|no|1000|200|'),
    ('12|poon|b-278 abv|criu|uio|50000|pyt|yes|no|2700|300|')

declare @tbl_collist table (colName varchar(100))
insert into @tbl_collist 
    (colName)
values
    ('ID'),
    ('customername'),
    ('prodname'),
    ('regency')

我想要一个类似下面的输出。

 id   customername   prodname    regency 
 11   jeev           uio         abap 
 12   poon           uio         pyt 
tsql sql-server-2014
2个回答
0
投票

然后复制dbo.DelimitedSplit8K的副本:

-- Sample Data
declare @tbl_rawData table (fileData varchar(max));
insert into @tbl_rawData (fileData)
values
    ('#Columns: ID|customername|addresss|agency|prodname|valuation|regency|ceptam|agan|yaha|citr'),
    ('11|jeev|a-161 kv|criu|uio|1800000|abap|yes|no|1000|200|'),
    ('12|poon|b-278 abv|criu|uio|50000|pyt|yes|no|2700|300|');

declare @tbl_collist table (colName varchar(100))
insert into @tbl_collist (colName)
values('ID'),('customername'),('prodname'),('regency');

-- Solution
WITH Split AS
(
  SELECT      s.ItemNumber
  FROM        @tbl_rawData AS t
  CROSS APPLY dbo.DelimitedSplit8K(t.fileData,'|') AS s
  JOIN        @tbl_collist AS c ON s.Item = c.colName 
                                OR (ItemNumber = 1 AND c.colName = 'ID')
  WHERE       t.fileData LIKE '#%'
)
SELECT 
  ID           = MAX(IIF(s.ItemNumber = 1, s.Item, NULL)),
  customername = MAX(IIF(s.ItemNumber = 2, s.Item, NULL)),
  prodname     = MAX(IIF(s.ItemNumber = 5, s.Item, NULL)),
  regency      = MAX(IIF(s.ItemNumber = 7, s.Item, NULL))
FROM        @tbl_rawData AS t
CROSS APPLY dbo.DelimitedSplit8K(t.fileData,'|') AS s
WHERE       t.fileData NOT LIKE '#%'
  AND       s.ItemNumber IN (SELECT split.ItemNumber FROM split)
GROUP BY    t.fileData;

返回:

ID  customername  prodname  regency    
--- ------------- --------- -----------
11  jeev          uio       abap
12  poon          uio       pyt

-1
投票

我可以建议您探索的一种方式:

DECLARE @delimiter VARCHAR(50)
SET @delimiter='|'  
;WITH CTE AS
( 
    SELECT
        CAST('' + REPLACE([fileData], @delimiter , '') + '' AS XML) 
        AS [Customer XML]
    FROM  @tbl_rawData 
)
SELECT
     [Customer XML].value('/M[1]', 'varchar(255)') As [Id],
     [Customer XML].value('/M[2]', 'varchar(255)') As [CustomerName],
     [Customer XML].value('/M[5]', 'varchar(255)') As [ProdName],
     [Customer XML].value('/M[7]', 'varchar(255)') As [Regency]
FROM CTE 
GO

想法是将列转换为xml,然后使用定界符将其拆分为多个列,然后选择所需的内容。

© www.soinside.com 2019 - 2024. All rights reserved.