четверг, 31 мая 2018 г.

Парсер строки с разделителями на T-SQL

Постановка задачи:
Имеется таблица, в одном поле которой записаны строки с названиями и разделителями. Необходимо преобразовать данные в таблицу в которой названия значений станут названиями полей, а сами значения будут записаны в соответствующую ячейку. Список может быть с пропусками.
Т. е. таблицу вида

(1, 'c3=01,c5=02,c6=03,c7=04,c8=05')
(2, 'c3=11,c5=12,c6=13,c7=14,c8=15')
(3, 'c3=21,c5=22,c6=23,c7=24,c8=25')
(4, 'c3=31,c5=32,c6=33,c7=34,c8=35')
(5, 'c3=41,c5=42,c6=43,c7=44,c8=45')
(6, 'c3=51,c5=52,c6=53,c9=54,c11=57,c12=58')
нужно преобразовать к



DECLARE @MainTable TABLE ( ID INT, DelimetedCol VARCHAR(1000) )
INSERT INTO @MainTable VALUES (1, 'c3=01,c5=02,c6=03,c7=04,c8=05')
INSERT INTO @MainTable VALUES (2, 'c3=11,c5=12,c6=13,c7=14,c8=15')
INSERT INTO @MainTable VALUES (3, 'c3=21,c5=22,c6=23,c7=24,c8=25')
INSERT INTO @MainTable VALUES (4, 'c3=31,c5=32,c6=33,c7=34,c8=35')
INSERT INTO @MainTable VALUES (5, 'c3=41,c5=42,c6=43,c7=44,c8=45')
INSERT INTO @MainTable VALUES (6, 'c3=51,c5=52,c6=53,c9=54,c11=57,c12=58')



; WITH CTE AS 
(
        SELECT    A.ID,
  B.IND_ROW,
                substring(B.IND_ROW,1,charindex('=',B.IND_ROW)-1) as section,

                reverse(substring(reverse(B.IND_ROW),0,charindex('=',reverse(B.IND_ROW)))) as val,

                ROW_NUMBER() OVER ( PARTITION BY A.ID ORDER BY A.ID) AS ROW_NUM

        FROM

        (
                SELECT    *,
                        CONVERT( XML, '<ROW>' + REPLACE( C.DelimetedCol, ',', '</ROW><ROW>' ) + '</ROW>' ) AS XML_ROW
                FROM    @MainTable C

        ) A

        CROSS APPLY

        (
                SELECT    DATA.ROW.value('.', 'VARCHAR(100)') AS IND_ROW
                FROM    A.XML_ROW.nodes('ROW') AS DATA(ROW)

        ) B

)

SELECT    ID
, [c3] AS COL_1
, [c5] AS COL_2
, [c6] AS COL_3
, [c7] AS COL_4
, [c8] AS COL_5
, [c9] AS COL_6
, [c11] AS COL_7
, [c12]

AS COL_8 FROM  (         SELECT   
  ID
  ,val
  ,section 
        FROM    CTE

)        AS SOURCE_TABLE

PIVOT

(    
        MAX(val) FOR section IN ( [c3], [c5], [c6], [c7], [c8], [c9], [c11], [c12])

)        AS PIVOT_TABLE

Комментариев нет:

Отправить комментарий