我借用了一些关于如何压缩和解压缩诊断代码字符串的代码,以便为我的数据仓库构建一个桥接表。它运作良好。但是,我只是不明白它是如何进行压缩的。这是以下代码的 SQL Fiddle
create table dimDiagnosisGroup (dxGroupKey int, dxCodeList nvarchar(1024))
insert into dimDiagnosisGroup
values (1,'042, 070.70, 722.10'),
(2,'042, 070.70, 780.52, 496, 716.90, 581.9'),
(3,'042, 070.70, 782.1, V58.69'),
(4,'042, 070.70, 782.3, V58.69')
WITH XMLTaggedList AS (
SELECT dxGroupKey,
CAST('<I>' + REPLACE(dxCodeList, ', ', '</I><I>') + '</I>' AS XML)
AS Diagnosis_Code_List
FROM dimDiagnosisGroup
)
SELECT dxGroupKey,
ExtractedDiagnosisList.X.value('.', 'VARCHAR(MAX)') AS dxCodeList2
FROM XMLTaggedList
CROSS APPLY Diagnosis_Code_List.nodes('//I') AS ExtractedDiagnosisList(X)
我理解XMLTaggedList部分很好。我不明白的是 Cross Apply 到ExtractedDiagnosisList(X),然后是ExtractedDiagnosisList.X.value('.', 'VARCHAR(MAX)')。
当我在 select 语句中将鼠标悬停在ExtractedDiagnosisList上时,SSMS 说它是一个派生表。但是,它对我来说有点像一个功能。我不明白Diagnosis_Code.List如何获取 .nodes('//I') 函数。最后,在 SQL 中, ExtractedDiagnosisList.X.value部分对我来说看起来很陌生。它看起来像 C# 等语言的语法。
您看到的是 SQL Server 中的 XQuery 实现。尽管 XQuery 使用自己的解析器并在查询编译阶段执行自己的代数化,但结果会与查询的 DML 部分一起组合和优化,然后组合成一个执行计划。
SQL Server 支持五种不同的方法。 value、exists、query和 nodes用于访问和转换数据。最后一个,modify,使用 XML DML 来修改数据。
value() 方法从 XML 实例返回一个标量值假设您有 xml:`
会给你第一个订单的第一个客户的 ID
在您的特定情况下,value('.') 意味着给我来自切碎元素的所有值(我稍后会谈到)请记住,在使用值函数时,您正在通过 XML 移动。现在为了使它更容易,不要“移动”太多,您可以使用功能节点将 XML 分解为关系数据。它返回一个行集,其中行表示由路径表达式标识的节点。
例子:
当您对表中的 XML 列使用 nodes() 方法时,您必须使用 APPLY 运算符。
例子:
我在值和节点上使用了示例,因为您仅提供了具有这两个功能的代码,如果您想了解更多信息,请访问此
希望这个简单的例子能让你了解如何查询 xml 类型
Cross Apply 与
.nodes()
XQuery 调用结合使用。这基本上是获取在CTE 语句中<I></I>
构造的 XML 数组的每个元素。XMLTaggedList
然后,外部.value()
XQuery 调用提取该值并将其强制转换为 aVARCHAR(MAX)
,为每个组中的每个代码返回一条记录。如果我分解查询,我发现更容易消化。也许你也会。
John Eisbrener 回答的附录:
就
ExtractedDiagnosisList(X)
部分而言,如果其中有空格,它可能会对我们中的一些人有所帮助:从SQL 文档中,派生表(和行集函数,以及 @variable.function_calls)不仅允许您指定表别名,还允许您指定相关“表”中返回的列的列别名列表。在本例中,只有一列,我们将其命名为
X
。看?
...
...
...
...