--- title: "General XQuery Use Cases | Microsoft Docs" ms.custom: "" ms.date: "03/07/2017" ms.prod: sql ms.prod_service: sql ms.reviewer: "" ms.technology: xml ms.topic: "language-reference" dev_langs: - "XML" helpviewer_keywords: - "XQuery, general usage cases" ms.assetid: 5187c97b-6866-474d-8bdb-a082634039cc author: "rothja" ms.author: "jroth" --- # General XQuery Use Cases [!INCLUDE[tsql-appliesto-ss2012-xxxx-xxxx-xxx-md](../includes/tsql-appliesto-ss2012-xxxx-xxxx-xxx-md.md)] This topic provides general examples of XQuery use. ## Examples ### A. Query catalog descriptions to find products and weights The following query returns the product model IDs and weights, if they exist, from the product catalog description. The query constructs XML that has the following form: ``` ... ``` This is the query: ``` SELECT CatalogDescription.query(' declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; { /p1:ProductDescription/p1:Specifications/Weight } ') as Result FROM Production.ProductModel WHERE CatalogDescription is not null ``` Note the following from the previous query: - The **namespace** keyword in the XQuery prolog defines a namespace prefix that is used in the query body. - The query body constructs the required XML. - In the WHERE clause, the **exist()** method is used to find only rows that contain product catalog descriptions. That is, the XML that contains the <`ProductDescription`> element. This is the result: ``` Varies with size. ``` The following query retrieves the same information, but only for those product models whose catalog description includes the weight, the <`Weight`> element, in the specifications, the <`Specifications`> element. This example uses WITH XMLNAMESPACES to declare the pd prefix and its namespace binding. In this way, the binding is not described in both the **query()** method and in the **exist()** method. ``` WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd) SELECT CatalogDescription.query(' { /pd:ProductDescription/pd:Specifications/Weight } ') as x FROM Production.ProductModel WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Specifications//Weight ') = 1 ``` In the previous query, the **exist()** method of the **xml** data type in the WHERE clause checks to see if there is a <`Weight`> element in the <`Specifications`> element. ### B. Find product model IDs for product models whose catalog descriptions include front-angle and small size pictures The XML product catalog description includes the product pictures, the <`Picture`> element. Each picture has several properties. These include the picture angle, the <`Angle`> element, and the size, the <`Size`> element. For product models whose catalog descriptions include front-angle and small-size pictures, the query constructs XML that has the following form: ``` < Product ProductModelID="..."> front small WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd) SELECT CatalogDescription.query(' { /pd:ProductDescription/pd:Picture/pd:Angle } { /pd:ProductDescription/pd:Picture/pd:Size } ') as Result FROM Production.ProductModel WHERE CatalogDescription.exist('/pd:ProductDescription/pd:Picture') = 1 AND CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Angle)[1]', 'varchar(20)') = 'front' AND CatalogDescription.value('(/pd:ProductDescription/pd:Picture/pd:Size)[1]', 'varchar(20)') = 'small' ``` Note the following from the previous query: - In the WHERE clause, the **exist()** method is used to retrieve only rows that have product catalog descriptions with the <`Picture`> element. - The WHERE clause uses the **value()** method two times to compare the values of the <`Size`> and <`Angle`> elements. This is a partial result: ``` front small ... ``` ### C. Create a flat list of the product model name and feature pairs, with each pair enclosed in the \ element In the product model catalog description, the XML includes several product features. All these features are included in the <`Features`> element. The query uses [XML Construction (XQuery)](../xquery/xml-construction-xquery.md) to construct the required XML. The expression in the curly braces is replaced by the result. ``` SELECT CatalogDescription.query(' declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; for $pd in /p1:ProductDescription, $f in $pd/p1:Features/* return { data($pd/@ProductModelName) } { $f } ') as x FROM Production.ProductModel WHERE ProductModelID=19 ``` Note the following from the previous query: - $pd/p1:Features/* returns only the element node children of <`Features`>, but $pd/p1:Features/node() returns all the nodes. This includes the element nodes, text nodes, processing instructions, and comments. - The two FOR loops generate a Cartesian product from which the product name and the individual feature are returned. - The **ProductName** is an attribute. The XML construction in this query returns it as an element. This is a partial result: ``` Mountain 100 19 3 year parts and labor Mountain 100 19 10 maintenance contact available through your dealer or any AdventureWorks retail store. ... ... ``` ### D. From the catalog description of a product model, list the product model name, model ID, and features grouped inside a \ element Using the information stored in the catalog description of the product model, the following query lists the product model name, model ID, and features grouped inside a \ element. ``` SELECT ProductModelID, CatalogDescription.query(' declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; { data(/pd:ProductDescription/@ProductModelName) } { data(/pd:ProductDescription/@ProductModelID) } { /pd:ProductDescription/pd:Features/* } ') as x FROM Production.ProductModel WHERE ProductModelID=19 ``` This is a partial result: ``` Mountain 100 19 ... ... High performance wheels. Anatomic design and made from durable leather for a full-day of riding in comfort. Top-of-the-line clipless pedals with adjustable tension. ... ``` ### E. Retrieve product model feature descriptions The following query constructs XML that includes a <`Product`> element that has **ProducModelID**, **ProductModelName** attributes, and the first two product features. Specifically, the first two product features are the first two child elements of the <`Features`> element. If there are more features, it returns an empty <`There-is-more/`> element. ``` SELECT CatalogDescription.query(' declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; { /pd:ProductDescription/@ProductModelID } { /pd:ProductDescription/@ProductModelName } { for $f in /pd:ProductDescription/pd:Features/*[position()<=2] return $f } { if (count(/pd:ProductDescription/pd:Features/*) > 2) then else () } ') as Result FROM Production.ProductModel WHERE CatalogDescription is not NULL ``` Note the following from the previous query: - The FOR ... RETURN loop structure retrieves the first two product features. The **position()** function is used to find the position of the elements in the sequence. ### F. Find element names from the product catalog description that end with "ons" The following query searches the catalog descriptions and returns all the elements in the <`ProductDescription`> element whose name ends with "ons". ``` SELECT ProductModelID, CatalogDescription.query(' declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; for $pd in /p1:ProductDescription/*[substring(local-name(.),string-length(local-name(.))-2,3)="ons"] return { $pd } ') as Result FROM Production.ProductModel WHERE CatalogDescription is not NULL ``` This is a partial result: ``` ProductModelID Result ----------------------------------------- 19 ... ``` ### G. Find summary descriptions that contain the word "Aerodynamic" The following query retrieves product models whose catalog descriptions contain the word "Aerodynamic" in the summary description: ``` WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS pd) SELECT ProductModelID, CatalogDescription.query(' { /pd:ProductDescription/@ProductModelID } { /pd:ProductDescription/pd:Summary } ') as Result FROM Production.ProductModel WHERE CatalogDescription.value(' contains( string( (/pd:ProductDescription/pd:Summary)[1] ),"Aerodynamic")','bit') = 1 ``` Note that the SELECT query specifies **query()** and **value()** methods of the **xml** data type. Therefore, instead of repeating the namespaces declaration two times in two difference query prologs, the prefix pd is used in the query and is defined only once by using WITH XMLNAMESPACES. Note the following from the previous query: - The WHERE clause is used to retrieve only the rows where the catalog description contains the word "Aerodynamic" in the <`Summary`> element. - The **contains()** function is used to see if the word is included in the text. - The **value()** method of the **xml** data type compares the value returned by **contains()** to 1. This is the result: ``` ProductModelID Result -------------- ------------------------------------------ 28 A TRUE multi-sport bike that offers streamlined riding and a revolutionary design. Aerodynamic design lets you ride with the pros, and the gearing will conquer hilly roads. ``` ### H. Find product models whose catalog descriptions do not include product model pictures The following query retrieves ProductModelIDs for product models whose catalog descriptions do no include a <`Picture`> element. ``` SELECT ProductModelID FROM Production.ProductModel WHERE CatalogDescription is not NULL AND CatalogDescription.exist('declare namespace p1="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; /p1:ProductDescription/p1:Picture ') = 0 ``` Note the following from the previous query: - If the **exist()** method in the WHERE clause returns False (0), the product model ID is returned. Otherwise, it is not returned. - Because all the product descriptions include a <`Picture`> element, the result set is empty in this case. ## See Also [XQueries Involving Hierarchy](../xquery/xqueries-involving-hierarchy.md) [XQueries Involving Order](../xquery/xqueries-involving-order.md) [XQueries Handling Relational Data](../xquery/xqueries-handling-relational-data.md) [String Search in XQuery](../xquery/string-search-in-xquery.md) [Handling Namespaces in XQuery](../xquery/handling-namespaces-in-xquery.md) [Add Namespaces to Queries with WITH XMLNAMESPACES](../relational-databases/xml/add-namespaces-to-queries-with-with-xmlnamespaces.md) [XML Data (SQL Server)](../relational-databases/xml/xml-data-sql-server.md) [XQuery Language Reference (SQL Server)](../xquery/xquery-language-reference-sql-server.md)