我有一个带有一个ML列的SQL表,我想查询该ML并获取id/@extension以及所有observation/code的列表.然而,它总是返回空结果.我已经分离了一个具有代表性测试数据的示例表,请参阅下文

CREATE TABLE study123 (
    ID integer,
    Title varchar(25),
    STXML XML
);

INSERT INTO study123 (
    ID,
    Title,
    STXML
) VALUES
(1, 'ST_Cardio', '<MeasurementDocument xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <id extension="68c65a01-2188-486c-adde-a854453ff817" />
  <code code="ST_Cardio" displayName="CardioLife60+" />
  <title>CardioLife 60+</title>
  <text>Prospective validation of CardioLife algorithms age 60+</text>
  <component>
    <section>
      <entry typeCode="DRIV">
        <observation classCode="OBS" moodCode="CRT">
          <code code="TMPL_1120000364" displayName="CV TEE/CARDIO DAILYLOG" />
        </observation>
      </entry>
      <entry typeCode="DRIV">
        <observation classCode="OBS" moodCode="CRT">
          <code code="TMPL_1120000365" displayName="CV TEE/CARDIO VITAL SIGNS CHECKLIST" />
        </observation>
      </entry>
    </section>
  </component>
</MeasurementDocument>'),
(2, 'ST_Diabetics', '<MeasurementDocument xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <id extension="a3be767f-1315-4e2b-ab4e-11a238d7f9a1" />
  <code code="ST_Diabetics" displayName="DiabeticsObs" />
  <title>Diabetics Observation 2023-2024</title>
  <text>Diabetics Observation 2023-2024 Extended II</text>
  <component>
    <section>
      <entry typeCode="DRIV">
        <observation classCode="OBS" moodCode="CRT">
          <code code="TMPL_1173900045" displayName="CVR PHYSIC DIABETICS" />
        </observation>
      </entry>
      <entry typeCode="DRIV">
        <observation classCode="OBS" moodCode="CRT">
          <code code="TMPL_1177400741" displayName="CVR DIABETICS OBSERVATIONWEEK" />
        </observation>
      </entry>
      <entry typeCode="DRIV">
        <observation classCode="OBS" moodCode="CRT">
          <code code="TMPL_1189600034" displayName="CVR DIABETICS REVALIDATION CHECKLIST" />
        </observation>
      </entry>
    </section>
  </component>
</MeasurementDocument>
');

这是我try 过的方法,但这只会给出所有空空的结果.当我try 仅查询每个研究的单个ID和文本描述时,列为空

-- test columns are all NULL(?)
SELECT 
    ID,
    Title,
    STXML,
    STXML.value('(/MeasurementDocument/id/@extension)[1]', 'nvarchar(100)') AS test_id,
    STXML.value('(/MeasurementDocument/title)[1]', 'nvarchar(100)') AS test_title,
    STXML.value('(/MeasurementDocument/text)[1]', 'nvarchar(100)') AS test_text
FROM 
    study123

当我try 查询每个研究的所有模板时,结果是空的,尽管第一个有2个模板,第二个有3个模板.

-- no records, empty result
select * from 
(select 
    ID,
    Title,
    TheTemplate.value('(./observation/code/@code)[1]', 'varchar(1000)') as tmpl_code
from 
    study123 CROSS APPLY
    STXML.nodes('MeasurementDocument/component/section/entry[@typeCode="DRIV"]/observation') AS AllTemplates(TheTemplate)
)  as Result

我try 搜索示例并询问ChatGPT,但我感觉查询ML的SQL服务器示例并不能很好地代表现实世界的html示例,或者它们缺少一些东西(?).

推荐答案

您需要使用WITH XMLNAMESPACES添加默认命名空间,并且您已经将observation node 增加了一倍.

您还可以避免使用另一个CROSS APLY nodes来引用根 node .

WITH XMLNAMESPACES (DEFAULT 'urn:hl7-org:v3')
SELECT 
    ID,
    Title,
    doc.value('(id/@extension)[1]', 'nvarchar(100)') AS test_id,
    doc.value('(title/text())[1]', 'nvarchar(100)') AS test_title,
    doc.value('(text/text())[1]', 'nvarchar(100)') AS test_text,
    TheTemplate.value('(code/@code)[1]', 'nvarchar(1000)') as tmpl_code
from 
    study123 s
CROSS APPLY
    s.STXML.nodes('MeasurementDocument') x1(doc)
CROSS APPLY
    x1.doc.nodes('component/section/entry[@typeCode="DRIV"]/observation') AS AllTemplates(TheTemplate);

db<>fiddle

Sql相关问答推荐

在SELECT陈述中使用子查询提高查询性能

调用存储过程时SQL服务器TDS协议响应问题

Postgresql -如何计算刷卡和刷卡时间

SQL查询以条件空值跟踪生产操作结果进展

Access 365将文本转换回BigInt

SQL:如何查找聚合满足条件的连续日期

PostgreSQL:按小时查看调整日期

如何隐藏聚合JSON数组元素的键

使用列表作为参数进行 Select ,如果为空,则在PostgreSQL中不使用参数进行 Select

用户购买平台及金额统计

在MS Access Modern图表的X轴上显示时间值时遇到问题

将JSON文件导入Postgres 16数据库时出错(22P04上次预期列之后的额外数据)

在VB.NET中如何在MS Access数据库中创建SQL项目历史库存卡

如何在T-SQL中编写row_number的WHERE子句?

使用 Oracle SQL Developer 将不同的列值转换为列会导致错误 ORA-01489

Postgres数据库维护:基于GROUP BY删除旧记录

oracle中多行的跨日期范围的交集

使用 PL/PGSQL 函数 Select 返回多条记录

Select 多年的日期范围

CURRENT_ROW 窗口框架上的 SQL 滞后