Okay, let me start with the obligatory mentoring comment:
You really need to normalize your data.
With that out of the way, this would be my approach to your situation. You can run/modify this example in SSMS.
First thing I did was create a sample environment that ( somewhat ) matched yours:
DECLARE @SurveyResults TABLE ( [Results] VARCHAR(1000), [Id] INT IDENTITY (1,1) );
INSERT INTO @SurveyResults ( [Results] )
VALUES
( 'Q1:null;Q2:very_satisified;Q3:null;Q4:null;Q5:null;Q6:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
, ( 'Q1:null;Q2:null;Q3:null;Q4:null;Q5:null;Q6:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
, ( 'Q1:physician_office;Q2:satisfied;Q3:other_reason;Q4:resolution_no;Q5:timely_yes;Q6:website_yes;Q7:no_reply;Q8:null;Q9:null;Q10:null;' );
Then I queried Results XML from SurveyResults:
SELECT
sr.Id
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q1"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q1
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q2"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q2
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q3"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q3
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q4"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q4
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q5"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q5
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q6"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q6
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q7"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q7
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q8"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q8
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q9"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q9
, NULLIF( qn.qnXml.value( 'data(//qn[name="Q10"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q10
FROM @SurveyResults sr
CROSS APPLY (
-- convert [Results] to parsable xml --
SELECT
CAST( '<qn><name>' + REPLACE( REPLACE( LEFT( Results, LEN( Results ) - 1 ), ':', '</name><val>' ), ';', '</val></qn><qn><name>' ) + '</val></qn>' AS XML ) AS qnXml
FROM @SurveyResults WHERE [Id] = sr.Id
) AS qn
ORDER BY
[Id];
Returns:
+----+------------------+-----------------+--------------+---------------+------------+-------------+----------+------+------+------+
| Id | Q1 | Q2 | Q3 | Q4 | Q5 | Q6 | Q7 | Q8 | Q9 | Q10 |
+----+------------------+-----------------+--------------+---------------+------------+-------------+----------+------+------+------+
| 1 | NULL | very_satisified | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 3 | physician_office | satisfied | other_reason | resolution_no | timely_yes | website_yes | no_reply | NULL | NULL | NULL |
+----+------------------+-----------------+--------------+---------------+------------+-------------+----------+------+------+------+
My example does not include your "Q4a" offshoots ( or the like ) and is making some major assumptions ( e.g. every Result has a trailing semi-colon ), however, I'm thinking there's enough here to get you started.
UPDATE BASED ON NEW DETAILS ( 08/16/2018 12:45 PM PST )
/*
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| ApplicationName | DNIS | Provider | AgentPeripheralNumber | PlanName | CaseNumber | StartTime | EndTime | CallId | Results |
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| AgentSurvey | 20xxx | 860xxxxxxx | 2xxxx | xxxxx | NULL | 2018-08-16 13:33:05.390 | 2018-08-16 13:33:22.127 | 10.xxx.xxx.xx.1534440785204.634158.AgentSurvey | Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null; |
| AgentSurvey | 20xxx | 508xxxxxxx | 2xxxx | xxxxxx | NULL | 2018-08-16 13:32:50.500 | 2018-08-16 13:33:11.643 | 10.xxx.xxx.xx.1534440770297.634125.AgentSurvey | Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null; |
| AgentSurvey | 20xxx | 408xxxxxxx | 2xxxx | xxxxxxxxx | D1096xxxxx | 2018-08-16 13:32:39.240 | 2018-08-16 13:32:57.630 | 10.xxx.xxx.xx.1534440759224.640875.AgentSurvey | Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null; |
| AgentSurvey | 20xxx | 860xxxxxxx | 2xxxx | xxxxx | NULL | 2018-08-16 13:32:12.217 | 2018-08-16 13:32:14.310 | 10.xxx.xxx.xx.1534440732030.634018.AgentSurvey | Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null; |
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
*/
-- create table variable --
DECLARE @SurveyResults TABLE ( ApplicationName VARCHAR(50), DNIS VARCHAR(10), [Provider] VARCHAR(10), AgentPeripheralNumber VARCHAR(255), PlanName VARCHAR(10), CaseNumber VARCHAR(10), StartTime DATETIME, EndTime DATETIME, CallId VARCHAR(255), Results VARCHAR(1000) );
-- insert data --
INSERT INTO @SurveyResults (
ApplicationName, DNIS, [Provider], AgentPeripheralNumber, PlanName, CaseNumber, StartTime, EndTime, CallId, Results
)
VALUES
( 'AgentSurvey', '20xxx', '860xxxxxxx', ' 2xxxx', 'xxxxx', NULL, '2018-08-16 13:33:05.390', '2018-08-16 13:33:22.127', '10.xxx.xxx.xx.1534440785204.634158.AgentSurvey', 'Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
, ( 'AgentSurvey', '20xxx', '508xxxxxxx', ' 2xxxx', 'xxxxxx', NULL, '2018-08-16 13:32:50.500', '2018-08-16 13:33:11.643', '10.xxx.xxx.xx.1534440770297.634125.AgentSurvey', 'Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
, ( 'AgentSurvey', '20xxx', '408xxxxxxx', ' 2xxxx', 'xxxxxxxxx', 'D1096xxxxx', '2018-08-16 13:32:39.240', '2018-08-16 13:32:57.630', '10.xxx.xxx.xx.1534440759224.640875.AgentSurvey', 'Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
, ( 'AgentSurvey', '20xxx', '860xxxxxxx', ' 2xxxx', 'xxxxx', NULL, '2018-08-16 13:32:12.217', '2018-08-16 13:32:14.310', '10.xxx.xxx.xx.1534440732030.634018.AgentSurvey', 'Q1:null;Q2:null;Q3:null;Q4:null;Q4a:null;Q5:null;Q6:null;Q6a:null;Q7:null;Q8:null;Q9:null;Q10:null;' )
-- preview data --
SELECT * FROM @SurveyResults ORDER BY StartTime;
-- query data --
-- removed NULLIFs for the sake of readability --
SELECT
sr.CallId
, qn.qnXml.value( 'data(//qn[name="Q1"]/val)[1]', 'VARCHAR(50)' ) AS Q1
, qn.qnXml.value( 'data(//qn[name="Q1a"]/val)[1]', 'VARCHAR(50)' ) AS Q1a
, qn.qnXml.value( 'data(//qn[name="Q2"]/val)[1]', 'VARCHAR(50)' ) AS Q2
, qn.qnXml.value( 'data(//qn[name="Q2a"]/val)[1]', 'VARCHAR(50)' ) AS Q2a
, qn.qnXml.value( 'data(//qn[name="Q3"]/val)[1]', 'VARCHAR(50)' ) AS Q3
, qn.qnXml.value( 'data(//qn[name="Q3a"]/val)[1]', 'VARCHAR(50)' ) AS Q3a
, qn.qnXml.value( 'data(//qn[name="Q4"]/val)[1]', 'VARCHAR(50)' ) AS Q4
, qn.qnXml.value( 'data(//qn[name="Q4a"]/val)[1]', 'VARCHAR(50)' ) AS Q4a
, qn.qnXml.value( 'data(//qn[name="Q5"]/val)[1]', 'VARCHAR(50)' ) AS Q5
, qn.qnXml.value( 'data(//qn[name="Q5a"]/val)[1]', 'VARCHAR(50)' ) AS Q5a
, qn.qnXml.value( 'data(//qn[name="Q6"]/val)[1]', 'VARCHAR(50)' ) AS Q6
, qn.qnXml.value( 'data(//qn[name="Q6a"]/val)[1]', 'VARCHAR(50)' ) AS Q6a
, qn.qnXml.value( 'data(//qn[name="Q7"]/val)[1]', 'VARCHAR(50)' ) AS Q7
, qn.qnXml.value( 'data(//qn[name="Q7a"]/val)[1]', 'VARCHAR(50)' ) AS Q7a
, qn.qnXml.value( 'data(//qn[name="Q8"]/val)[1]', 'VARCHAR(50)' ) AS Q8
, qn.qnXml.value( 'data(//qn[name="Q8a"]/val)[1]', 'VARCHAR(50)' ) AS Q8a
, qn.qnXml.value( 'data(//qn[name="Q9"]/val)[1]', 'VARCHAR(50)' ) AS Q9
, qn.qnXml.value( 'data(//qn[name="Q9a"]/val)[1]', 'VARCHAR(50)' ) AS Q9a
, qn.qnXml.value( 'data(//qn[name="Q10"]/val)[1]', 'VARCHAR(50)' ) AS Q10
, qn.qnXml.value( 'data(//qn[name="Q10a"]/val)[1]', 'VARCHAR(50)' ) AS Q10a
FROM @SurveyResults sr
CROSS APPLY (
-- convert [Results] to parsable xml --
SELECT
CAST( '<qn><name>' + REPLACE( REPLACE( LEFT( Results, LEN( Results ) - 1 ), ':', '</name><val>' ), ';', '</val></qn><qn><name>' ) + '</val></qn>' AS XML ) AS qnXml
FROM @SurveyResults where [CallId] = sr.CallId
) qn
ORDER BY
sr.StartTime;
Returns ( 4 rows only, as expected ):
+------------------------------------------------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| CallId | Q1 | Q1a | Q2 | Q2a | Q3 | Q3a | Q4 | Q4a | Q5 | Q5a | Q6 | Q6a | Q7 | Q7a | Q8 | Q8a | Q9 | Q9a | Q10 | Q10a |
+------------------------------------------------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 10.xxx.xxx.xx.1534440732030.634018.AgentSurvey | null | NULL | null | NULL | null | NULL | null | null | null | NULL | null | null | null | NULL | null | NULL | null | NULL | null | NULL |
| 10.xxx.xxx.xx.1534440759224.640875.AgentSurvey | null | NULL | null | NULL | null | NULL | null | null | null | NULL | null | null | null | NULL | null | NULL | null | NULL | null | NULL |
| 10.xxx.xxx.xx.1534440770297.634125.AgentSurvey | null | NULL | null | NULL | null | NULL | null | null | null | NULL | null | null | null | NULL | null | NULL | null | NULL | null | NULL |
| 10.xxx.xxx.xx.1534440785204.634158.AgentSurvey | null | NULL | null | NULL | null | NULL | null | null | null | NULL | null | null | null | NULL | null | NULL | null | NULL | null | NULL |
+------------------------------------------------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
This works for me.