用于筛选出具有特定属性值的 XML 节点的 SQL 查询

SQL query to filter out XML nodes that has a particular attribute value

提问人:bdfios 提问时间:2/22/2023 更新时间:2/23/2023 访问量:112

问:

我想使用 SQL 查询在以下 XML 中仅过滤 Junk 为 true 的节点。我喜欢做的是常规 SQL 中的“select * from main where junk=true”;

这是我要查询的 XML。

    <Main>
      <Box>
        <Name>Box1</Name>
        <Junk>false</Junk>
      </Box>
      <Box>
        <Name>Box2</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box3</Name>
        <Junk>false</Junk>
      </Box>
      <Box>
        <Name>Box4</Name>
        <Junk>false</Junk>
      </Box>
      <Box>
        <Name>Box5</Name>
        <Junk>false</Junk>
      </Box>
      <Box>
        <Name>Box6</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box7</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box8</Name>
        <Junk>false</Junk>
      </Box>
    </Main>

我尝试了以下方法:

    declare @main xml;
    declare @junk xml;

    set @main = '';

    set @junk = (select  @main WHERE @main.value('(/Main/Junk)[1]', 'nvarchar(10)')  = 'true');

但它总是返回所有列表。

如何更新此查询以仅返回 Junk = true 的节点?

预期结果:

    <Main>
      <Box>
        <Name>Box2</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box6</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box7</Name>
        <Junk>true</Junk>
      </Box>
    </Main>

    <Box>
        <Name>Box2</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box6</Name>
        <Junk>true</Junk>
      </Box>
      <Box>
        <Name>Box7</Name>
        <Junk>true</Junk>
      </Box>
jquery sql xml where-子句

评论

0赞 SebCza 2/22/2023
这取决于你使用哪种方言PLSQL、PgSQL、TSQL?
0赞 jjdesign 2/22/2023
也许你忘记了 Box 节点看这里/Main/Box/Junk
0赞 bdfios 2/23/2023
我正在使用 SQL。
0赞 bdfios 2/23/2023
@jjdesign,你能在这里添加你的解决方案,以便我将其标记为答案吗?那个外部链接明天可能就不起作用了,谁知道呢。

答:

1赞 jjdesign 2/23/2023 #1

在正确的 T-SQL XML 中,这将是

SELECT
   x.query('.')
FROM @main.nodes('/Main/Box') a(x) 
WHERE 
      x.value('(Junk)[1]', 'nvarchar(10)')  = 'true'
FOR XML PATH(''),ROOT('Main')