我有一项业务要求,将SQL输出修改为不同的字段。
例如,我有一个表格SurveyResults并将问题和答案记录在单列中。
select * from SurveyResults
输出:
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| 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; |
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
现在,企业希望在多列中查看此数据。像下面这样。
输出:
XXXXXX 2XXXX Phy .. sat .. other .. res .. XXXXXX 2XXXX phy .. case .. null
我可以通过简单地修改我的表来做到这一点,但是我做不到,因为它依赖于不同的应用程序,这将是一项繁琐的任务。
使用您的查询:
SELECT sr.CallId,sr.PlanName,sr.Provider,sr.CaseNumber,sr.StartTime
, 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="Q4a"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q4a
, 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="Q6a"]/val)[1]', 'VARCHAR(50)' ), 'null' ) AS Q6a
, 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 [CallId] = sr.CallId
) AS qn
ORDER BY
StartTime desc;
立即获取此错误: 消息9411,第16级,状态1,第1行 XML解析:第1行,字符45,应使用分号
答案 0 :(得分:1)
好的,让我从强制性的指导评论开始: 您确实需要规范化数据。
顺便说一句,这将是我处理您的情况的方法。您可以在SSMS中运行/修改此示例。
我要做的第一件事是创建一个(有点)与您的环境相匹配的示例环境:
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;' );
然后我从SurveyResults中查询结果XML:
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];
返回:
+----+------------------+-----------------+--------------+---------------+------------+-------------+----------+------+------+------+
| 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 |
+----+------------------+-----------------+--------------+---------------+------------+-------------+----------+------+------+------+
我的示例不包括您的“ Q4a”分支(或类似内容),并且做出了一些主要假设(例如,每个Result都有尾随的分号),但是,我认为这里已经足够让您入门。
基于新细节的更新(PST 2018年8月16日下午12:45)
/*
+-----------------+-------+------------+-----------------------+-----------+------------+-------------------------+-------------------------+------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| 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;
返回(按预期仅 4行):
+------------------------------------------------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 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 |
+------------------------------------------------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
这对我有用。