Extract data under subheadings from a text column in SQL Server

5jdjgkvh  于 2023-04-28  发布在  SQL Server
关注(0)|答案(2)|浏览(102)

I have a text field in a table. The field has subheadings and I want to extract the data under each subheading and create a columns named after the subheading.

For example:

ID.      Text
1        NAME: abc.  COMPANY: cuz.  ADDRESS: dfg

Required output:

ID  Name Company Address
1.   abc  Cuz    dfg

I tried substring with charindex to get the position of the Subheading, but I am unable to get the length right. The text under each subheading is of variable length.

py49o6xq

py49o6xq1#

Updated considering new information. In the future, please be more careful and considerate

Example

Declare @YourTable Table ([ID] varchar(50),[Text] varchar(50))  Insert Into @YourTable Values 
 (1,'Name: abc Company: cuz Address: dfg')
,(2,'Name: xyz Company: bis Address: Fabtown')
 
Select ID
      ,C.*
 From @YourTable A
 Cross Apply ( values ( replace(replace([Text],'Company:','||Company:'),'Address:','||Address:') ) ) B(NewStr)
 Cross Apply (
    Select Name    = ltrim(rtrim(replace(max(case when Value like '%Name:%'    then Value end),'Name:'   ,'')))
          ,Company = ltrim(rtrim(replace(max(case when Value like '%Company:%' then Value end),'Company:','')))
          ,Address = ltrim(rtrim(replace(max(case when Value like '%Address:%' then Value end),'Address:','')))
     From  OpenJSON( '["'+replace(string_escape(NewStr,'json'),'||','","')+'"]' )
 ) C

Results

ID  Name    Company Address
1   abc     cuz     dfg
2   xyz     bis     Fabtown
btqmn9zl

btqmn9zl2#

As others have stated, you should provide more data. But I will take a guess at what you want. Note that there are quite a few assumptions here.

Either way, this is what I would do.

Note that depending on indexes, volume of data, etc., you may need to use interim tables (I personally like to use temp tables).

IF OBJECT_ID(N'tempdb..#t') IS NOT NULL DROP TABLE #t
SELECT t.* INTO #t
FROM (
SELECT 1 AS ID,
'Name: abc
Company: cuz
Address: dfg' AS [Text]
UNION
SELECT 2 AS ID,
'Name: xyz
Company: !!!
Address: something else' AS [Text]
UNION
SELECT 3 AS ID,
'Name: qwe
Company: @@@
Address: 123456780' AS [Text]
    ) AS t

--Identify break character
DECLARE @BreakCharacter NVARCHAR(100) = CHAR(13)

--Normalize the data so that there are not multiple "breaks"
UPDATE #t
SET [Text] = REPLACE(REPLACE([Text], CHAR(13) + CHAR(10),CHAR(13)), CHAR(10), CHAR(13))

--use CTE to iterate over the text and break it apart
;WITH t AS (
SELECT ID, CAST([Text] AS NVARCHAR(100)) AS [Text], CAST([Text] AS NVARCHAR(100)) AS Remaining, 0 AS Iteration
FROM #t
UNION ALL
SELECT ID,
    CAST(CASE WHEN Remaining LIKE '%' + @BreakCharacter + '%' THEN LEFT(Remaining, CHARINDEX(@BreakCharacter, Remaining)-1) ELSE Remaining END  AS NVARCHAR(100)),
    CAST(CASE WHEN Remaining LIKE '%' + @BreakCharacter + '%' THEN STUFF(Remaining, 1, CHARINDEX(@BreakCharacter, Remaining),'') END            AS NVARCHAR(100)),
    Iteration + 1
FROM t
WHERE Remaining IS NOT NULL 
)
SELECT *
FROM(
    SELECT
        ID,
        LTRIM(RTRIM(LEFT([Text],CHARINDEX(':',[Text])-1))) AS Field,
        STUFF([Text],1,CHARINDEX(':',[Text]),'') AS Value
    FROM t
    WHERE Iteration > 0
) AS p--Alias to pivot
PIVOT (MAX(Value) FOR Field IN ([Name], [Company],[Address])) AS t--alias for the final dataset

相关问题