查找列表是否包含多个值 - SQL Server Xquery

时间:2018-05-14 18:02:35

标签: sql-server xquery-sql

我将XML数据存储到名为BikeTable的表中。 XML数据来自使用.Net序列化程序序列化的对象。 BikeTable看起来像这样:

Id - UniqueIdentifier
XmlData - XML

XmlData列中存储的XML如下所示:

记录1:

<Bike>
    <Material>
        <Cage>EIECH</Cage>
        <Mpn>B258-C436-B001</
    </Material>
    <Roles>
        <string>Race</string>
        <string>Mountain</string>
        <string>City</string>
    </Roles>
</Bike>

记录2:

<Bike>
    <Material>
        <Cage>ABCDE</Cage>
        <Mpn>B258-C436-B001</Mpn>
    </Material>
    <Roles>
        <string>Race</string>
    </Roles>
</Bike>

我希望能够在我的表格中找到包含例如Race和Mountain的记录。

示例,如果我想要包含&#39; Road&#39;和&#39; Mountain&#34;的记录的ID。我发现的唯一方法就是这样:

select Id 
from BikeTable
where XmlData.exist('/Bike/Roles/string[contains(., "Road")]') = 1 
   or XmlData.exist('/Bike/Roles/string[contains(., "Mountain")]') = 1

我不喜欢这个选项,因为如果我想查找匹配一个或多个角色的记录,它会强制我生成查询。 角色可以包含无限数量的值,我需要能够找到一个或多个值的记录。 例如:包含Race的记录,包含Race或Montain的记录,包含City的记录,包含City和Mountain的记录等。

有没有办法知道列表是否包含多个值?

1 个答案:

答案 0 :(得分:0)

是的,你可以。这有点猜测,正如你所说,你想做SELECT *;没有桌子的DDL就无法提供任何数据的东西。因此,相反,我已经归还了自行车的Cage和Mpn:

CREATE TABLE BikeTable (xmlData xml);

--The Close tag for Mpn was missing in your sample data, I assume it wasn't mean to be
INSERT INTO BikeTable
VALUES('<Bike>
    <Material>
        <Cage>EIECH</Cage>
        <Mpn>B258-C436-B001</Mpn>
    </Material>
    <Roles>
        <string>Race</string>
        <string>Mountain</string>
        <string>City</string>
    </Roles>
</Bike>')
GO
WITH Bikes AS (
    SELECT B.Material.value('(Cage/text())[1]','varchar(15)') AS Cage, --Data Type guessed
           B.Material.value('(Mpn/text())[1]','varchar(15)') AS Mpn, --Data Type guessed
           BR.String.value('(./text())[1]','varchar(15)') AS String --Data Type guessed
    FROM BikeTable BT
         CROSS APPLY BT.xmlData.nodes('/Bike/Material') B(Material)
         CROSS APPLY BT.xmlData.nodes('/Bike/Roles/string') BR(String))
SELECT Cage, Mpn
FROM Bikes
GROUP BY Cage, Mpn
HAVING COUNT(String) > 1;

GO

DROP TABLE BikeTable;