Reputation: 1304
I have 2 questions:
I am trying to filter attribute @Type = "Bikes"
in the below example. But I am getting all 6 rows. I should get only 3 rows. Why exist not working here, I have no Idea?
How to filter further @Type = "Bikes" and Product = "Mountain"
My code mentioned below:
declare @xml xml = '<StoreSurvey>
<AnnualSales>800000</AnnualSales>
<AnnualRevenue>80000</AnnualRevenue>
<BankName>United Security</BankName>
<BusinessType>BM</BusinessType>
<YearOpened>1996</YearOpened>
<Specialty>Mountain</Specialty>
<SquareFeet>21000</SquareFeet>
<Brands>2</Brands>
<Internet>ISDN</Internet>
<NumberEmployees>13</NumberEmployees>
<Products Type="Bikes">
<Product>Mountain</Product>
<Product>Road</Product>
<Product>Racing</Product>
</Products>
<Products Type="Clothes">
<Product>Jerseys</Product>
<Product>Jackets</Product>
<Product>Shorts</Product>
</Products>
</StoreSurvey>'
Code for question 1:
select T.col.value('.','varchar(100)')
from @xml.nodes('/StoreSurvey/Products/Product') as T(col)
where T.col.exist('/StoreSurvey/Products[@Type = "Bikes"]') =1
Desired output:
Mountain
Road
Racing
Code for question 2: this code is causing "syntax error":
select T.col.value('.','varchar(100)')
from @xml.nodes('/StoreSurvey/Products/Product') as T(col)
where T.col.exist('/StoreSurvey/Products[@Type = "Bikes"]/[Product = "Mountain"]') = 1
Upvotes: 1
Views: 48
Reputation: 89101
For both of those, use a query form like this:
with q as
(
select products.col.value('@Type','varchar(100)') ProductType,
product.col.value('.','varchar(100)') Product
from @xml.nodes('/StoreSurvey/Products') as products(col)
cross apply products.col.nodes('Product') as product(col)
)
select *
from q
where ProductType = 'Bikes'
and Product = 'Mountain';
Upvotes: 1
Reputation: 453327
Both of these return your desired first result
select T.col.value('.','varchar(100)')
from @xml.nodes('/StoreSurvey/Products/Product') as T(col)
where T.col.exist('..[@Type = "Bikes"]') =1
The second one seems more natural as it is strange to get all Product
nodes then back up and apply a filter on the parent axis (with ..
)
select T.col.value('.','varchar(100)')
from @xml.nodes('/StoreSurvey/Products[@Type = "Bikes"]/Product') as T(col)
It is not clear what your exact desired results are for Q2 but this returns a result
select T.col.value('.','varchar(100)')
from @xml.nodes('/StoreSurvey/Products[@Type = "Bikes"]/Product[text() = "Mountain"]') as T(col)
Upvotes: 2