You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2722 lines
96 KiB
2722 lines
96 KiB
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--XSLT Processor: SAXON 9.1.0.5 from Saxonica SAXON 9.1.0.5-->
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<html lang="EN" xmlns="http://www.w3.org/1999/xhtml" xml:lang="EN">
|
|
<head>
|
|
<meta name="generator" content=
|
|
"HTML Tidy for Windows (vers 14 February 2006), see www.w3.org" />
|
|
<title>XQuery 3.0 Use Cases</title>
|
|
|
|
<style type="text/css">
|
|
/*<![CDATA[*/
|
|
code { font-family: monospace; }
|
|
|
|
div.constraint,
|
|
div.issue,
|
|
div.note,
|
|
div.notice { margin-left: 2em; }
|
|
|
|
div.issue
|
|
p.title { margin-left: -2em; }
|
|
|
|
ol.enumar { list-style-type: decimal; }
|
|
ol.enumla { list-style-type: lower-alpha; }
|
|
ol.enumlr { list-style-type: lower-roman; }
|
|
ol.enumua { list-style-type: upper-alpha; }
|
|
ol.enumur { list-style-type: upper-roman; }
|
|
|
|
li p { margin-top: 0.3em;
|
|
margin-bottom: 0.3em; }
|
|
|
|
sup small { font-style: italic;
|
|
color: #8F8F8F;
|
|
}
|
|
|
|
div.exampleInner pre { margin-left: 1em;
|
|
margin-top: 0em; margin-bottom: 0em}
|
|
div.exampleOuter {border: 4px double gray;
|
|
margin: 0em; padding: 0em}
|
|
div.exampleInner { background-color: #d5dee3;
|
|
border-top-width: 4px;
|
|
border-top-style: double;
|
|
border-top-color: #d3d3d3;
|
|
border-bottom-width: 4px;
|
|
border-bottom-style: double;
|
|
border-bottom-color: #d3d3d3;
|
|
padding: 4px; margin: 0em }
|
|
div.exampleWrapper { margin: 4px }
|
|
div.exampleHeader { font-weight: bold;
|
|
margin: 4px}
|
|
|
|
div.issue { border-bottom-color: black;
|
|
border-bottom-style: solid;
|
|
border-bottom-width: 1pt;
|
|
margin-bottom: 20pt;
|
|
}
|
|
|
|
th.issue-toc-head { border-bottom-color: black;
|
|
border-bottom-style: solid;
|
|
border-bottom-width: 1pt;
|
|
}
|
|
|
|
/*]]>*/
|
|
</style>
|
|
<link rel="stylesheet" type="text/css" href=
|
|
"http://www.w3.org/StyleSheets/TR/W3C-WD.css" />
|
|
</head>
|
|
<body>
|
|
<div class="head">
|
|
<p><a href="http://www.w3.org/"><img src=
|
|
"http://www.w3.org/Icons/w3c_home" alt="W3C" height="48" width=
|
|
"72" /></a></p>
|
|
<h1><a name="title" id="title"></a>XQuery 3.0 Use Cases</h1>
|
|
<h2><a name="w3c-doctype" id="w3c-doctype"></a>W3C Working Draft 14
|
|
December 2010</h2>
|
|
<dl>
|
|
<dt>This version:</dt>
|
|
<dd><a href=
|
|
"http://www.w3.org/TR/2010/WD-xquery-30-use-cases-20101214/">http://www.w3.org/TR/2010/WD-xquery-30-use-cases-20101214/</a></dd>
|
|
<dt>Latest version:</dt>
|
|
<dd><a href=
|
|
"http://www.w3.org/TR/xquery-30-use-cases/">http://www.w3.org/TR/xquery-30-use-cases/</a></dd>
|
|
<dt>Previous versions:</dt>
|
|
<dd><a href=
|
|
"http://www.w3.org/TR/2008/WD-xquery-11-use-cases-20081203/">http://www.w3.org/TR/2008/WD-xquery-11-use-cases-20081203/,</a>
|
|
<a href=
|
|
"http://www.w3.org/TR/2008/WD-xquery-11-use-cases-20080711/">http://www.w3.org/TR/2008/WD-xquery-11-use-cases-20080711/</a></dd>
|
|
<dt>Editor:</dt>
|
|
<dd>Tim Kraska, FLWOR Foundation <a href=
|
|
"mailto:tim@flworfound.org"><tim@flworfound.org></a></dd>
|
|
</dl>
|
|
<p>This document is also available in these non-normative formats:
|
|
<a href="xquery-30-use-cases.xml">XML</a>.</p>
|
|
<p class="copyright"><a href=
|
|
"http://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2010 <a href="http://www.w3.org/"><acronym title="World Wide Web Consortium">W3C</acronym></a><sup>®</sup>
|
|
(<a href="http://www.csail.mit.edu/"><acronym title=
|
|
"Massachusetts Institute of Technology">MIT</acronym></a>, <a href=
|
|
"http://www.ercim.eu/"><acronym title=
|
|
"European Research Consortium for Informatics and Mathematics">ERCIM</acronym></a>,
|
|
<a href="http://www.keio.ac.jp/">Keio</a>), All Rights Reserved.
|
|
W3C <a href=
|
|
"http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
|
|
<a href=
|
|
"http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>
|
|
and <a href=
|
|
"http://www.w3.org/Consortium/Legal/copyright-documents">document
|
|
use</a> rules apply.</p>
|
|
</div>
|
|
<hr />
|
|
<div>
|
|
<h2><a name="abstract" id="abstract"></a>Abstract</h2>
|
|
<p>This document specifies usage scenarios for XML Query (XQuery)
|
|
3.0.</p>
|
|
</div>
|
|
<div>
|
|
<h2><a name="status" id="status"></a>Status of this Document</h2>
|
|
<p><em>This section describes the status of this document at the
|
|
time of its publication. Other documents may supersede this
|
|
document. A list of current W3C publications and the latest
|
|
revision of this technical report can be found in the <a href=
|
|
"http://www.w3.org/TR/">W3C technical reports index</a> at
|
|
http://www.w3.org/TR/.</em></p>
|
|
<p>This is a <a href=
|
|
"http://www.w3.org/2005/10/Process-20051014/tr.html#maturity-levels">
|
|
Working Draft</a> as described in the <a href=
|
|
"http://www.w3.org/2005/10/Process-20051014/tr.html">Process
|
|
Document</a>. It has been developed by the W3C <a href=
|
|
"http://www.w3.org/XML/Query/">XML Query Working Group</a>, which
|
|
is part of the <a href="http://www.w3.org/XML/Activity">XML
|
|
Activity</a>. The Working Group expects to eventually publish this
|
|
document as a Working Group Note.</p>
|
|
<p>This document provides a number of use cases designed to
|
|
evaluate XQuery 3.0, the requirements for which are specified in
|
|
<a href="#xquery-30-requirements">[XQuery 3.0 Requirements]</a>.
|
|
Organizations and individuals should review this document to
|
|
ascertain whether or not adequate coverage of the requirements is
|
|
provided by these use cases.</p>
|
|
<p>This Working Draft is being published concurrently with the
|
|
XQuery 3.0 spec published on the same date. It has been updated to
|
|
include additional use cases and to align it with the correct
|
|
syntax of XQuery 3.0.</p>
|
|
<p>Please report errors in this document using W3C's <a href=
|
|
"http://www.w3.org/Bugs/Public/">public Bugzilla system</a>
|
|
(instructions can be found at <a href=
|
|
"http://www.w3.org/XML/2005/04/qt-bugzilla">http://www.w3.org/XML/2005/04/qt-bugzilla</a>).
|
|
If access to that system is not feasible, you may send your
|
|
comments to the W3C XSLT/XPath/XQuery public comments mailing list,
|
|
<a href=
|
|
"mailto:public-qt-comments@w3.org">public-qt-comments@w3.org</a>.
|
|
It will be very helpful if you include the string “[XQuery30UC]” in
|
|
the subject line of your report, whether made in Bugzilla or in
|
|
email. Please use multiple Bugzilla entries (or, if necessary,
|
|
multiple email messages) if you have more than one comment to make.
|
|
Archives of the comments and responses are available at <a href=
|
|
"http://lists.w3.org/Archives/Public/public-qt-comments/">http://lists.w3.org/Archives/Public/public-qt-comments/</a>.</p>
|
|
<p>Publication as a Working Draft does not imply endorsement by the
|
|
W3C Membership. This is a draft document and may be updated,
|
|
replaced or obsoleted by other documents at any time. It is
|
|
inappropriate to cite this document as other than work in
|
|
progress.</p>
|
|
<p>This document was produced by a group operating under the
|
|
<a href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5
|
|
February 2004 W3C Patent Policy</a>. W3C maintains a <a href=
|
|
"http://www.w3.org/2004/01/pp-impl/18797/status#disclosures">public
|
|
list of any patent disclosures</a> made in connection with the
|
|
deliverables of the group; that page also includes instructions for
|
|
disclosing a patent. An individual who has actual knowledge of a
|
|
patent which the individual believes contains <a href=
|
|
"http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">
|
|
Essential Claim(s)</a> must disclose the information in accordance
|
|
with <a href=
|
|
"http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">
|
|
section 6 of the W3C Patent Policy</a>.</p>
|
|
</div>
|
|
<div class="toc">
|
|
<h2><a name="contents" id="contents"></a>Table of Contents</h2>
|
|
<p class="toc">1 <a href="#ucforxq30">Use Cases for XML Query
|
|
3.0</a><br />
|
|
2 <a href="#data">Shopping Scenario: Schema and Data</a><br />
|
|
    2.1 <a href="#dtdproducts">Schema</a><br />
|
|
    2.2 <a href="#dataproducts">Sample
|
|
Data</a><br />
|
|
3 <a href="#groupby">Use Case "Group By" - Queries which require
|
|
value-based grouping</a><br />
|
|
    3.1 <a href="#d2e229">Schema and Sample
|
|
Data</a><br />
|
|
        3.1.1 <a href=
|
|
"#dtdbooks">Schema Q7-Q8</a><br />
|
|
        3.1.2 <a href=
|
|
"#databooks">Sample Data Q7-Q8</a><br />
|
|
    3.2 <a href=
|
|
"#groupby-queries-results">Queries and Results</a><br />
|
|
        3.2.1 <a href=
|
|
"#groupby_q1">Q1</a><br />
|
|
        3.2.2 <a href=
|
|
"#groupby_q2">Q2</a><br />
|
|
        3.2.3 <a href=
|
|
"#groupby_q3">Q3</a><br />
|
|
        3.2.4 <a href=
|
|
"#groupby_q4">Q4</a><br />
|
|
        3.2.5 <a href=
|
|
"#groupby_q5">Q5</a><br />
|
|
        3.2.6 <a href=
|
|
"#groupby_q6">Q6</a><br />
|
|
        3.2.7 <a href=
|
|
"#groupby_b1">Q7</a><br />
|
|
        3.2.8 <a href=
|
|
"#groupby_b2">Q8</a><br />
|
|
4 <a href="#windowing">Use Case "Windowing" - Queries which require
|
|
windowing</a><br />
|
|
    4.1 <a href="#d2e431">Schema and Sample
|
|
Data</a><br />
|
|
        4.1.1 <a href=
|
|
"#dtdarrange_rows">XML Schema for Q1</a><br />
|
|
        4.1.2 <a href=
|
|
"#dataarrange_rows">Sample Data for Q1</a><br />
|
|
        4.1.3 <a href=
|
|
"#dtdhead_para">XML Schema for Q2</a><br />
|
|
        4.1.4 <a href=
|
|
"#datahead_para">Sample Data for Q2</a><br />
|
|
        4.1.5 <a href=
|
|
"#dtdterm_def_list">XML Schema for Q3</a><br />
|
|
        4.1.6 <a href=
|
|
"#dataterm_def_list">Sample Data for Q3</a><br />
|
|
        4.1.7 <a href=
|
|
"#dtddelayed_events_day1">XML Schema for Q4-Q6</a><br />
|
|
        4.1.8 <a href=
|
|
"#datadelayed_events_day1">Sample Data for Q4-Q6</a><br />
|
|
        4.1.9 <a href=
|
|
"#dtdday1">XML Schema for Q7-Q13</a><br />
|
|
        4.1.10 <a href=
|
|
"#dataday1">Sample Data for Q7-Q13</a><br />
|
|
        4.1.11 <a href=
|
|
"#dtdrss">XML Schema for Q14-Q16</a><br />
|
|
        4.1.12 <a href=
|
|
"#datarss">Sample Data for Q14-Q16</a><br />
|
|
        4.1.13 <a href=
|
|
"#dtdcXML">XML Schema for Q17-Q19</a><br />
|
|
        4.1.14 <a href=
|
|
"#datacXML">Sample Data for Q17-Q19</a><br />
|
|
    4.2 <a href=
|
|
"#windowing-queries-results">Queries and Results</a><br />
|
|
        4.2.1 <a href=
|
|
"#windowing_arrange_rows">Q1</a><br />
|
|
        4.2.2 <a href=
|
|
"#windowing_head_para">Q2</a><br />
|
|
        4.2.3 <a href=
|
|
"#windowing_term_def_list">Q3</a><br />
|
|
        4.2.4 <a href=
|
|
"#windowing_1moving_avarage_time">Q4</a><br />
|
|
        4.2.5 <a href=
|
|
"#windowing_2exponential_smoothing_1">Q5</a><br />
|
|
        4.2.6 <a href=
|
|
"#windowing_3outlier_detection">Q6</a><br />
|
|
        4.2.7 <a href=
|
|
"#windowing_1SEQ_A1h">Q7</a><br />
|
|
        4.2.8 <a href=
|
|
"#windowing_2SEQ_TimePerPerson">Q8</a><br />
|
|
        4.2.9 <a href=
|
|
"#windowing_2SEQ_TimePerPerson_overall">Q9</a><br />
|
|
        4.2.10 <a href=
|
|
"#windowing_3Seq_Not_A">Q10</a><br />
|
|
        4.2.11 <a href=
|
|
"#windowing_4SEQ_yA">Q11</a><br />
|
|
        4.2.12 <a href=
|
|
"#windowing_5NOSEQ_BothIn">Q12</a><br />
|
|
        4.2.13 <a href=
|
|
"#windowing_6AGG_Enter_3X_1">Q13</a><br />
|
|
        4.2.14 <a href=
|
|
"#windowing_annoying_authors">Q14</a><br />
|
|
        4.2.15 <a href=
|
|
"#windowing_interesting_topics">Q15</a><br />
|
|
        4.2.16 <a href=
|
|
"#windowing_summary_by_authors">Q16</a><br />
|
|
        4.2.17 <a href=
|
|
"#windowing_Q2_most_valuable_customer">Q17</a><br />
|
|
        4.2.18 <a href=
|
|
"#windowing_Q3_transaction_time">Q18</a><br />
|
|
        4.2.19 <a href=
|
|
"#windowing_Q4_ship_together">Q19</a><br />
|
|
5 <a href="#count-use-cases">Use Case "Count" - Queries which
|
|
require output numbering</a><br />
|
|
    5.1 <a href="#d2e942">Schema and Sample
|
|
Data</a><br />
|
|
    5.2 <a href="#d2e950">Queries and
|
|
Results</a><br />
|
|
        5.2.1 <a href=
|
|
"#count-numbering">Q1</a><br />
|
|
        5.2.2 <a href=
|
|
"#count-windowing">Q2</a><br />
|
|
        5.2.3 <a href=
|
|
"#count-top-k">Q3</a><br />
|
|
6 <a href="#outer-join-uc">Use Case "Outer For" - Queries which
|
|
require outer joins</a><br />
|
|
    6.1 <a href="#d2e1025">Schema and Sample
|
|
Data</a><br />
|
|
    6.2 <a href="#d2e1033">Queries and
|
|
Results</a><br />
|
|
        6.2.1 <a href=
|
|
"#outer-join-1">Q1</a><br />
|
|
        6.2.2 <a href=
|
|
"#simplified-flwor-2">Q2</a><br />
|
|
7 <a href="#try-catch-use-cases">Use Case "Try-Catch" - Queries
|
|
which require to recover from errors</a><br />
|
|
    7.1 <a href="#dataerrorproducts">Sample
|
|
Data</a><br />
|
|
    7.2 <a href="#d2e1096">Queries and
|
|
Results</a><br />
|
|
        7.2.1 <a href=
|
|
"#try-catch-1">Q1</a><br />
|
|
        7.2.2 <a href=
|
|
"#try-catch-2">Q2</a><br />
|
|
        7.2.3 <a href=
|
|
"#try-catch-3">Q3</a><br /></p>
|
|
<h3><a name="appendices" id="appendices"></a>Appendices</h3>
|
|
<p class="toc">A <a href="#acknowledgements">Acknowledgements</a>
|
|
(Non-Normative)<br />
|
|
B <a href="#ChangeLog">Change Log</a> (Non-Normative)<br />
|
|
    B.1 <a href="#id-2008-01-30">30 January
|
|
2008</a><br />
|
|
    B.2 <a href="#id-2008-11-17">17 November
|
|
2008</a><br />
|
|
C <a href="#references">References</a> (Non-Normative)<br /></p>
|
|
</div>
|
|
<hr />
|
|
<div class="body">
|
|
<div class="div1">
|
|
<h2><a name="ucforxq30" id="ucforxq30"></a>1 Use Cases for XML
|
|
Query 3.0</h2>
|
|
<p>The use cases listed below were created by the XML Query Working
|
|
Group to illustrate important applications for the new features in
|
|
XQuery 3.0. Each use case is focused on a specific application
|
|
area, and contains a XML Schema and example input data. Each use
|
|
case specifies a set of queries that might be applied to the input
|
|
data, and the expected results for each query. Since the English
|
|
description of each query is concise, the expected results form an
|
|
important part of the definition of each query, specifying the
|
|
expected output format.</p>
|
|
<p>Most of the listed use cases are based on a simple shopping
|
|
scenario described in section <a href="#data">Schema and Data</a>.
|
|
Use cases which require special data have a seperate subsection
|
|
describing the XML Schema and input data. All use cases assume that
|
|
input is provided in the form of one or more documents with
|
|
specific names. For instance, the products in a document may be
|
|
accessed with expressions like this:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
doc("products.xml")//product
|
|
</pre></div>
|
|
<p>Several implementors have asked us to make the queries from
|
|
these use cases available in a separate file in order to make it
|
|
easier for them to test their parsers. These queries may be found
|
|
in <a href="#UseCaseQueries">[Use Case Sample Queries]</a></p>
|
|
<p>To make output more readable, the output of queries has been
|
|
formatted using whitespace which may not be returned by a query
|
|
processor. This whitespace should not be considered normative for
|
|
the correctness of results.</p>
|
|
<p>These queries were tested with a dynamic implementation of
|
|
XQuery. Some queries may require additional type declarations to be
|
|
used with an implementation that implements the Static Typing
|
|
feature.</p>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="data" id="data"></a>2 Shopping Scenario: Schema and
|
|
Data</h2>
|
|
<p>If not stated otherwise all use cases in this document are based
|
|
on a simplified shopping scenario containing three documents. The
|
|
first document, products.xml, contains a list of products, whereas
|
|
stores.xml includes a list of stores, and sales-records.xml
|
|
contains the list of sales.</p>
|
|
<div class="div2">
|
|
<h3><a name="dtdproducts" id="dtdproducts"></a>2.1 Schema</h3>
|
|
<p>The document product.xml uses the following XML Schema:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="products">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="product" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="name" type="xs:string"/>
|
|
<xs:element name="category" type="xs:string"/>
|
|
<xs:element name="price" type="xs:double"/>
|
|
<xs:element name="cost" type="xs:double"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
<p>The sales-records.xml document follows this XML Schema:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="sales">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="record" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="product-name" type="xs:string"/>
|
|
<xs:element name="store-number" type="xs:integer"/>
|
|
<xs:element name="qty" type="xs:integer"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
<p>The stores.xml document is valid to this XML Schema:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="stores">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="store" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="store-number" type="xs:byte"/>
|
|
<xs:element name="state" type="xs:string"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="dataproducts" id="dataproducts"></a>2.2 Sample
|
|
Data</h3>
|
|
<p>The content of the document products.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="products.xsd">
|
|
<product>
|
|
<name>broiler</name>
|
|
<category>kitchen</category>
|
|
<price>100</price>
|
|
<cost>70</cost>
|
|
</product>
|
|
<product>
|
|
<name>toaster</name>
|
|
<category>kitchen</category>
|
|
<price>30</price>
|
|
<cost>10</cost>
|
|
</product>
|
|
<product>
|
|
<name>blender</name>
|
|
<category>kitchen</category>
|
|
<price>50</price>
|
|
<cost>25</cost>
|
|
</product>
|
|
<product>
|
|
<name>socks</name>
|
|
<category>clothes</category>
|
|
<price>5</price>
|
|
<cost>2</cost>
|
|
</product>
|
|
<product>
|
|
<name>shirt</name>
|
|
<category>clothes</category>
|
|
<price>10</price>
|
|
<cost>3</cost>
|
|
</product>
|
|
</products>
|
|
</pre></div>
|
|
<p>The content of sales-records.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<sales xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="sales.xsd">
|
|
<record>
|
|
<product-name>broiler</product-name>
|
|
<store-number>1</store-number>
|
|
<qty>20</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>toaster</product-name>
|
|
<store-number>2</store-number>
|
|
<qty>100</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>toaster</product-name>
|
|
<store-number>2</store-number>
|
|
<qty>50</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>toaster</product-name>
|
|
<store-number>3</store-number>
|
|
<qty>50</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>blender</product-name>
|
|
<store-number>3</store-number>
|
|
<qty>100</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>blender</product-name>
|
|
<store-number>3</store-number>
|
|
<qty>150</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>socks</product-name>
|
|
<store-number>1</store-number>
|
|
<qty>500</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>socks</product-name>
|
|
<store-number>2</store-number>
|
|
<qty>10</qty>
|
|
</record>
|
|
<record>
|
|
<product-name>shirt</product-name>
|
|
<store-number>3</store-number>
|
|
<qty>10</qty>
|
|
</record>
|
|
</sales>
|
|
</pre></div>
|
|
<p>The content of stores.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<stores xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="stores.xsd">
|
|
<store>
|
|
<store-number>1</store-number>
|
|
<state>CA</state>
|
|
</store>
|
|
<store>
|
|
<store-number>2</store-number>
|
|
<state>CA</state>
|
|
</store>
|
|
<store>
|
|
<store-number>3</store-number>
|
|
<state>MA</state>
|
|
</store>
|
|
<store>
|
|
<store-number>4</store-number>
|
|
<state>WA</state>
|
|
</store>
|
|
</stores>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="groupby" id="groupby"></a>3 Use Case "Group By" -
|
|
Queries which require value-based grouping</h2>
|
|
<p>This use case contains several sample queries in which value
|
|
based grouping is needed.</p>
|
|
<div class="div2">
|
|
<h3><a name="d2e229" id="d2e229"></a>3.1 Schema and Sample
|
|
Data</h3>
|
|
<p>Queries 1-6 are based on a simplified shop scenario with
|
|
products, sales records and different shop locations. The schema
|
|
and data can be found in section <a href="#data">Schema and
|
|
Data</a>. Queries 7 and 8 are based on a bibliography document
|
|
shown below:</p>
|
|
<div class="div3">
|
|
<h4><a name="dtdbooks" id="dtdbooks"></a>3.1.1 Schema Q7-Q8</h4>
|
|
<p>Q7 and Q8 use an input document named "books.xml", with the
|
|
following XML Schema:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="bib">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="book" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="author" type="xs:string" maxOccurs="unbounded"/>
|
|
<xs:element name="title" type="xs:string"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="databooks" id="databooks"></a>3.1.2 Sample Data
|
|
Q7-Q8</h4>
|
|
<p>Here are the contents of books.xml:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<bib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="books.xsd">
|
|
<book>
|
|
<author>Jim Melton</author>
|
|
<author>Alan Simon</author>
|
|
<title>SQL:1999</title>
|
|
</book>
|
|
<book>
|
|
<author>Jim Melton</author>
|
|
<title>Advanced SQL:1999</title>
|
|
</book>
|
|
<book>
|
|
<author>Alan Simon</author>
|
|
<title>Strategic Database Technology</title>
|
|
</book>
|
|
<book>
|
|
<author>Jim Melton</author>
|
|
<author>Andrew Eisenberg</author>
|
|
<title>Understanding SQL and Java Together</title>
|
|
</book>
|
|
<book>
|
|
<author>Jim Melton</author>
|
|
<author>Stephen Buxton</author>
|
|
<title>Querying XML</title>
|
|
</book>
|
|
</bib>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="groupby-queries-results" id=
|
|
"groupby-queries-results"></a>3.2 Queries and Results</h3>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q1" id="groupby_q1"></a>3.2.1 Q1</h4>
|
|
<p>Group sales by product, list name and total quantity of each
|
|
product.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<sales-qty-by-product>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $pname := $sales/product-name
|
|
group by $pname
|
|
order by $pname
|
|
return
|
|
<product name="{$pname}">{
|
|
sum($sales/qty)
|
|
}</product>
|
|
}</sales-qty-by-product>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<sales-qty-by-product>
|
|
<product name="blender">250</product>
|
|
<product name="broiler">20</product>
|
|
<product name="shirt">10</product>
|
|
<product name="socks">510</product>
|
|
<product name="toaster">200</product>
|
|
</sales-qty-by-product>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q2" id="groupby_q2"></a>3.2.2 Q2</h4>
|
|
<p>Group sales by state (a property of the store) and category (a
|
|
property of the product). Order groups by the grouping keys. For
|
|
each group, show the total quantity sold.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $state := doc("stores.xml")/*/store[store-number = $sales/store-number]/state
|
|
let $category := doc("products.xml")/*/product[name = $sales/product-name]/category
|
|
group by $state, $category
|
|
order by $state, $category
|
|
return
|
|
<group>
|
|
{$state, $category}
|
|
<total-qty>{sum($sales/qty)}</total-qty>
|
|
</group>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<group>
|
|
<state>CA</state>
|
|
<category>clothes</category>
|
|
<total-qty>510</total-qty>
|
|
</group>
|
|
<group>
|
|
<state>CA</state>
|
|
<category>kitchen</category>
|
|
<total-qty>170</total-qty>
|
|
</group>
|
|
<group>
|
|
<state>MA</state>
|
|
<category>clothes</category>
|
|
<total-qty>10</total-qty>
|
|
</group>
|
|
<group>
|
|
<state>MA</state>
|
|
<category>kitchen</category>
|
|
<total-qty>300</total-qty>
|
|
</group>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q3" id="groupby_q3"></a>3.2.3 Q3</h4>
|
|
<p>Group sales by state (a property of the store) and category (a
|
|
property of the product). Order groups by the grouping keys. For
|
|
each group, show the total revenue (defined as sales/qty *
|
|
product/price).</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $state := doc("stores.xml")/*/store[store-number = $sales/store-number]/state,
|
|
$product := doc("products.xml")/*/product[name = $sales/product-name],
|
|
$category := $product/category,
|
|
$revenue := $sales/qty * $product/price
|
|
group by $state, $category
|
|
order by $state, $category
|
|
return
|
|
<group>
|
|
{$state, $category}
|
|
<total-revenue>{sum($revenue)}</total-revenue>
|
|
</group>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<group>
|
|
<state>CA</state>
|
|
<category>clothes</category>
|
|
<total-revenue>2550</total-revenue>
|
|
</group>
|
|
<group>
|
|
<state>CA</state>
|
|
<category>kitchen</category>
|
|
<total-revenue>6500</total-revenue>
|
|
</group>
|
|
<group>
|
|
<state>MA</state>
|
|
<category>clothes</category>
|
|
<total-revenue>100</total-revenue>
|
|
</group>
|
|
<group>
|
|
<state>MA</state>
|
|
<category>kitchen</category>
|
|
<total-revenue>14000</total-revenue>
|
|
</group>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q4" id="groupby_q4"></a>3.2.4 Q4</h4>
|
|
<p>Combine the input documents into a three-level hierarchy based
|
|
on state, category, and product. At the product level, show the
|
|
total quantity sold of each product. List items alphabetically at
|
|
each level of the hierarchy.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $store in doc("stores.xml")/*/store
|
|
let $state := $store/state
|
|
group by $state
|
|
order by $state
|
|
return
|
|
<state name="{$state}">{
|
|
for $product in doc("products.xml")/*/product
|
|
let $category := $product/category
|
|
group by $category
|
|
order by $category
|
|
return
|
|
<category name="{$category}">{
|
|
for $sales in doc("sales-records.xml")/*/record[store-number = $store/store-number
|
|
and product-name = $product/name]
|
|
let $pname := $sales/product-name
|
|
group by $pname
|
|
order by $pname
|
|
return
|
|
<product name="{$pname}" total-qty="{sum($sales/qty)}" />
|
|
}</category>
|
|
}</state>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<state name="CA">
|
|
<category name="clothes">
|
|
<product name="socks" total-qty="510"/>
|
|
</category>
|
|
<category name="kitchen">
|
|
<product name="broiler" total-qty="20"/>
|
|
<product name="toaster" total-qty="150"/>
|
|
</category>
|
|
</state>
|
|
<state name="MA">
|
|
<category name="clothes">
|
|
<product name="shirt" total-qty="10"/>
|
|
</category>
|
|
<category name="kitchen">
|
|
<product name="blender" total-qty="250"/>
|
|
<product name="toaster" total-qty="50"/>
|
|
</category>
|
|
</state>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q5" id="groupby_q5"></a>3.2.5 Q5</h4>
|
|
<p>List all stores in ascending order by store number. For each
|
|
store, list the products sold in that store, in descending order by
|
|
quantity sold. Illustrates ordering among and within groups.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $storeno := $sales/store-number
|
|
group by $storeno
|
|
order by $storeno
|
|
return
|
|
<store number = "{$storeno}">{
|
|
for $s in $sales
|
|
order by xs:int($s/qty) descending
|
|
return
|
|
<product name = "{$s/product-name}" qty = "{$s/qty}"/>
|
|
}</store>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<store number="1">
|
|
<product name="socks" qty="500"/>
|
|
<product name="broiler" qty="20"/>
|
|
</store>
|
|
<store number="2">
|
|
<product name="toaster" qty="100"/>
|
|
<product name="toaster" qty="50"/>
|
|
<product name="socks" qty="10"/>
|
|
</store>
|
|
<store number="3">
|
|
<product name="blender" qty="150"/>
|
|
<product name="blender" qty="100"/>
|
|
<product name="toaster" qty="50"/>
|
|
<product name="shirt" qty="10"/>
|
|
</store>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_q6" id="groupby_q6"></a>3.2.6 Q6</h4>
|
|
<p>List all stores whose total profit is greater than 100, in
|
|
descending order by total profit. Note: total profit for a store is
|
|
the sum over all sales in that store, of the quantity sold times
|
|
the difference between price and cost for the item sold.
|
|
Illustrates cross-document computation, filtering of groups,
|
|
ordering by a non-grouping key.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $storeno := $sales/store-number,
|
|
$product := doc("products.xml")/*/product[name = $sales/product-name],
|
|
$prd := $product,
|
|
$profit := $sales/qty * ($prd/price - $prd/cost)
|
|
group by $storeno
|
|
let $total-store-profit := sum($profit)
|
|
where $total-store-profit > 100
|
|
order by $total-store-profit descending
|
|
return
|
|
<store number = "{$storeno}" total-profit = "{$total-store-profit}"/>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<store number="3" total-profit="7320"/>
|
|
<store number="2" total-profit="3030"/>
|
|
<store number="1" total-profit="2100"/>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_b1" id="groupby_b1"></a>3.2.7 Q7</h4>
|
|
<p>Group books by author. Create a group for each individual
|
|
author. A book with multiple authors should appear in the groups
|
|
for each of its authors. Alphabetize the authors and the book
|
|
titles within each author group.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $book in doc("books.xml")/*/book
|
|
for $author in $book/author
|
|
group by $author
|
|
order by $author
|
|
return
|
|
<author name="{$author}">{
|
|
for $b in $book
|
|
order by $b/title
|
|
return
|
|
<title> {fn:data($b/title)} </title>
|
|
}</author>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<author name="Alan Simon">
|
|
<title>SQL:1999</title>
|
|
<title>Strategic Database Technology</title>
|
|
</author>
|
|
<author name="Andrew Eisenberg">
|
|
<title>Understanding SQL and Java Together</title>
|
|
</author>
|
|
<author name="Jim Melton">
|
|
<title>Advanced SQL:1999</title>
|
|
<title>Querying XML</title>
|
|
<title>SQL:1999</title>
|
|
<title>Understanding SQL and Java Together</title>
|
|
</author>
|
|
<author name="Stephen Buxton">
|
|
<title>Querying XML</title>
|
|
</author>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="groupby_b2" id="groupby_b2"></a>3.2.8 Q8</h4>
|
|
<p>Group books by author. Create a group for each distinct ordered
|
|
list of authors. Each book should be grouped with other books that
|
|
have the same ordered list of authors. Alphabetize the book titles
|
|
within each group.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $book in doc("books.xml")/*/book
|
|
let $author-list := fn:string-join($book/author, ', ')
|
|
group by $author-list
|
|
order by $author-list
|
|
return
|
|
<author-list names="{$author-list}">{
|
|
for $b in $book
|
|
order by $b/title
|
|
return
|
|
<title> {fn:data($b/title)} </title>
|
|
}</author-list>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<author-list names="Alan Simon">
|
|
<title>Strategic Database Technology</title>
|
|
</author-list>
|
|
<author-list names="Jim Melton">
|
|
<title>Advanced SQL:1999</title>
|
|
</author-list>
|
|
<author-list names="Jim Melton, Alan Simon">
|
|
<title>SQL:1999</title>
|
|
</author-list>
|
|
<author-list names="Jim Melton, Andrew Eisenberg">
|
|
<title>Understanding SQL and Java Together</title>
|
|
</author-list>
|
|
<author-list names="Jim Melton, Stephen Buxton">
|
|
<title>Querying XML</title>
|
|
</author-list>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="windowing" id="windowing"></a>4 Use Case "Windowing" -
|
|
Queries which require windowing</h2>
|
|
<p>This use case covers queries that require windowing or
|
|
positional grouping, which can be seen as a special form of
|
|
windowing. Windowing means that the queries require selecting
|
|
subsequences based on certain characterisics of an underlying
|
|
sequence.</p>
|
|
<div class="div2">
|
|
<h3><a name="d2e431" id="d2e431"></a>4.1 Schema and Sample
|
|
Data</h3>
|
|
<p>Windowing is required in various scenarios from formatting up to
|
|
streaming applications. The listed queries try to cover different
|
|
scenarios and require therefore also various types of input data.
|
|
The following sections describe for every query the used data and
|
|
the according schema.</p>
|
|
<div class="div3">
|
|
<h4><a name="dtdarrange_rows" id="dtdarrange_rows"></a>4.1.1 XML
|
|
Schema for Q1</h4>
|
|
<p>Q1 uses an input document named arrange_rows.xml, with the
|
|
following XML Schema arrange_rows.xsd:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="doc">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="data" type="xs:string" maxOccurs="unbounded"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dataarrange_rows" id="dataarrange_rows"></a>4.1.2
|
|
Sample Data for Q1</h4>
|
|
<p>The content of arrange_rows.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="arrange_rows.xsd">
|
|
<data>Green</data>
|
|
<data>Pink</data>
|
|
<data>Lilac</data>
|
|
<data>Turquoise</data>
|
|
<data>Peach</data>
|
|
<data>Opal</data>
|
|
<data>Champagne</data>
|
|
</doc>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtdhead_para" id="dtdhead_para"></a>4.1.3 XML Schema
|
|
for Q2</h4>
|
|
<p>Q2 uses an input document named head_para.xml, with the
|
|
following XML Schema named head_para.xsd:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="body">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:sequence maxOccurs="unbounded">
|
|
<xs:element name="h2" type="xs:string"/>
|
|
<xs:element name="p" type="xs:string" maxOccurs="unbounded"/>
|
|
</xs:sequence>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="datahead_para" id="datahead_para"></a>4.1.4 Sample
|
|
Data for Q2</h4>
|
|
<p>The content of head_para.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="head_para.xsd">
|
|
<h2>heading1</h2>
|
|
<p>para1</p>
|
|
<p>para2</p>
|
|
<h2>heading2</h2>
|
|
<p>para3</p>
|
|
<p>para4</p>
|
|
<p>para5</p>
|
|
</body>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtdterm_def_list" id="dtdterm_def_list"></a>4.1.5 XML
|
|
Schema for Q3</h4>
|
|
<p>Q3 uses an input document named term_def_list.xml, with the
|
|
following XML Schema named term_def_list.xsd:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="doc">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:sequence maxOccurs="unbounded">
|
|
<xs:element name="dt" type="xs:string" maxOccurs="unbounded"/>
|
|
<xs:element name="dd" type="xs:string" maxOccurs="unbounded"/>
|
|
</xs:sequence>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dataterm_def_list" id="dataterm_def_list"></a>4.1.6
|
|
Sample Data for Q3</h4>
|
|
<p>The content of term_def_list.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="term_def_list.xsd">
|
|
<dt>XML</dt>
|
|
<dd>Extensible Markup Language</dd>
|
|
<dt>XSLT</dt>
|
|
<dt>XSL Transformations</dt>
|
|
<dd>A language for transforming XML</dd>
|
|
<dd>A specification produced by W3C</dd>
|
|
</doc>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtddelayed_events_day1" id=
|
|
"dtddelayed_events_day1"></a>4.1.7 XML Schema for Q4-Q6</h4>
|
|
<p>Q4 - Q6 use an input document named temp_events.xml, with the
|
|
following XML Schema named temp_events.xsd:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="stream">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="event" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:attribute name="time" type="xs:integer" use="required"/>
|
|
<xs:attribute name="temp" type="xs:double" use="required"/>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="datadelayed_events_day1" id=
|
|
"datadelayed_events_day1"></a>4.1.8 Sample Data for Q4-Q6</h4>
|
|
<p>The content of temp_events.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<stream xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="temp_events.xsd">
|
|
<event temp="10" time="1"/>
|
|
<event temp="8" time="2"/>
|
|
<event temp="6" time="3"/>
|
|
<event temp="13" time="4"/>
|
|
<event temp="33" time="5"/>
|
|
<event temp="10" time="6"/>
|
|
<event temp="10" time="7"/>
|
|
</stream>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtdday1" id="dtdday1"></a>4.1.9 XML Schema for
|
|
Q7-Q13</h4>
|
|
<p>Q7 - Q13 use an input document named person_events.xml, with the
|
|
following XML Schema named person_events.xsd:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="stream">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="event" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:sequence minOccurs="0">
|
|
<xs:element name="person" type="xs:string"/>
|
|
<xs:element name="direction" type="xs:string"/>
|
|
</xs:sequence>
|
|
<xs:attribute name="time" type="xs:dateTime" use="required"/>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dataday1" id="dataday1"></a>4.1.10 Sample Data for
|
|
Q7-Q13</h4>
|
|
<p>The content of person_events.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<stream xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="person_events.xsd">
|
|
<event time="2006-01-01T01:00:00-00:00"/>
|
|
<event time="2006-01-01T10:30:00-00:00">
|
|
<person>Anton</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-01T11:00:00-00:00">
|
|
<person>Barbara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-01T11:15:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-01T12:15:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-01T14:00:00-00:00">
|
|
<person>Barbara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-01T15:00:00-00:00">
|
|
<person>Anton</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-01T23:00:00-00:00"/>
|
|
<event time="2006-01-02T01:00:00-00:00"/>
|
|
<event time="2006-01-02T11:00:00-00:00">
|
|
<person>Anton</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:00:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:10:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:15:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:20:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:25:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-02T12:40:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-02T14:00:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>in</direction>
|
|
</event>
|
|
<event time="2006-01-02T16:00:00-00:00">
|
|
<person>Anton</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-02T16:15:00-00:00">
|
|
<person>Clara</person>
|
|
<direction>out</direction>
|
|
</event>
|
|
<event time="2006-01-02T23:00:00-00:00"/>
|
|
</stream>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtdrss" id="dtdrss"></a>4.1.11 XML Schema for
|
|
Q14-Q16</h4>
|
|
<p>Q14 - Q16 use as input document a slightly modified RSS document
|
|
named rss.xml. It mainly differs from RSS 2.0 in the way dates are
|
|
expressed in the data. The XML Schema, rss.xsd, is as follows:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="rss">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="channel">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="title" type="xs:string"/>
|
|
<xs:element name="link" type="xs:anyURI"/>
|
|
<xs:element name="description" type="xs:string"/>
|
|
<xs:element name="language" type="xs:string"/>
|
|
<xs:element ref="item" maxOccurs="unbounded"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
<xs:element name="item">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:element name="title" type="xs:string"/>
|
|
<xs:element name="category" type="xs:string"/>
|
|
<xs:element name="author" type="xs:string"/>
|
|
<xs:element name="pubDate" type="xs:dateTime"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="datarss" id="datarss"></a>4.1.12 Sample Data for
|
|
Q14-Q16</h4>
|
|
<p>The content of rss.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="rss.xsd">
|
|
<channel>
|
|
<title>DBIS RSS</title>
|
|
<link>http://www.dbis.ethz.ch</link>
|
|
<description>The windowing dummy RSS.</description>
|
|
<language>en-us</language>
|
|
<item>
|
|
<title>Why use cases are important Part 1.</title>
|
|
<category>Workshop</category>
|
|
<author>rokas@e-mail.de</author>
|
|
<pubDate>2003-06-03T09:00:00</pubDate>
|
|
</item>
|
|
<item>
|
|
<title>Why use cases are important Part 2.</title>
|
|
<category>Workshop</category>
|
|
<author>rokas@e-mail.de</author>
|
|
<pubDate>2003-06-03T09:00:00</pubDate>
|
|
</item>
|
|
<item>
|
|
<title>Why use cases are important Part 3.</title>
|
|
<category>Workshop</category>
|
|
<author>rokas@e-mail.de</author>
|
|
<pubDate>2003-06-03T10:00:00</pubDate>
|
|
</item>
|
|
<item>
|
|
<title>Extending XQuery with Window Functions</title>
|
|
<category>Talk</category>
|
|
<author>tim@e-mail.de</author>
|
|
<pubDate>2003-06-03T11:00:00</pubDate>
|
|
</item>
|
|
<item>
|
|
<title>XQueryP: A new programming language is born</title>
|
|
<category>Talk</category>
|
|
<author>david@e-mail.de</author>
|
|
<pubDate>2003-06-03T12:00:00</pubDate>
|
|
</item>
|
|
<item>
|
|
<title>Why use cases are annoying to write.</title>
|
|
<category>Talk</category>
|
|
<author>rokas@e-mail.de</author>
|
|
<pubDate>2003-06-04T10:00:00</pubDate>
|
|
</item>
|
|
</channel>
|
|
</rss>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="dtdcXML" id="dtdcXML"></a>4.1.13 XML Schema for
|
|
Q17-Q19</h4>
|
|
<p>Q17-Q19 use an input document named cxml.xml. The structure of
|
|
this document is inspired by the Commerce XML Resource standard
|
|
(cXML). The document contains a sequence of events, where an event
|
|
corresponds to a simplified message of the cXML standard or an
|
|
timeclock event. The XML Schema with the file-name cxml.xsd is as
|
|
follows:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
<xs:element name="sequence">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:choice maxOccurs="unbounded">
|
|
<xs:element name="time" type="TimeEvent"/>
|
|
<xs:element name="OrderRequest" type="OrderRequest" maxOccurs="unbounded"/>
|
|
<xs:element name="ConfirmationRequest" type="ConfirmationRequest"/>
|
|
<xs:element name="ShipNotice" type="ShipNotice" maxOccurs="unbounded"/>
|
|
</xs:choice>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
<xs:complexType name="TimeEvent">
|
|
<xs:attribute name="date" type="xs:dateTime" use="required"/>
|
|
</xs:complexType>
|
|
<xs:complexType name="OrderRequest">
|
|
<xs:sequence>
|
|
<xs:element name="Item" maxOccurs="unbounded">
|
|
<xs:complexType>
|
|
<xs:attribute name="unitPrice" type="xs:byte" use="required"/>
|
|
<xs:attribute name="quantity" type="xs:byte" use="required"/>
|
|
<xs:attribute name="partID" type="xs:string" use="required"/>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:sequence>
|
|
<xs:attribute name="type" type="xs:string" use="required"/>
|
|
<xs:attribute name="total" type="xs:short" use="required"/>
|
|
<xs:attribute name="shipTo" type="xs:string"/>
|
|
<xs:attribute name="orderID" type="xs:string" use="required"/>
|
|
<xs:attribute name="date" type="xs:dateTime" use="required"/>
|
|
<xs:attribute name="billTo" type="xs:string" use="required"/>
|
|
</xs:complexType>
|
|
<xs:complexType name="ConfirmationRequest">
|
|
<xs:attribute name="status" type="xs:string" use="required"/>
|
|
<xs:attribute name="orderID" type="xs:string" use="required"/>
|
|
<xs:attribute name="date" type="xs:dateTime" use="required"/>
|
|
<xs:attribute name="confirmID" type="xs:string" use="required"/>
|
|
</xs:complexType>
|
|
<xs:complexType name="ShipNotice">
|
|
<xs:attribute name="orderID" type="xs:string" use="required"/>
|
|
<xs:attribute name="date" type="xs:dateTime" use="required"/>
|
|
</xs:complexType>
|
|
</xs:schema>
|
|
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="datacXML" id="datacXML"></a>4.1.14 Sample Data for
|
|
Q17-Q19</h4>
|
|
<p>The content of cxml.xml is:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<sequence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="cxml.xsd">
|
|
<time date="2006-01-01T00:00:00-00:00"/>
|
|
<OrderRequest billTo="ACME1" date="2006-01-01T10:00:00-00:00"
|
|
orderID="OID01" shipTo="ACME1" total="1100" type="new">
|
|
<Item partID="ID1" quantity="10" unitPrice="100"/>
|
|
<Item partID="ID2" quantity="10" unitPrice="10"/>
|
|
</OrderRequest>
|
|
<OrderRequest billTo="ACME2" date="2006-01-01T11:00:00-00:00"
|
|
orderID="OID02" total="100" type="new">
|
|
<Item partID="ID2" quantity="10" unitPrice="10"/>
|
|
</OrderRequest>
|
|
<ConfirmationRequest confirmID="C1" date="2006-01-01T18:00:00-00:00"
|
|
orderID="OID02" status="reject"/>
|
|
<time date="2006-01-02T00:00:00-00:00"/>
|
|
<ConfirmationRequest confirmID="C1" date="2006-01-02T08:00:00-00:00"
|
|
orderID="OID01" status="accept"/>
|
|
<OrderRequest billTo="ACME1" date="2006-01-02T14:00:00-00:00"
|
|
orderID="OID03" shipTo="ACME1" total="10000" type="new">
|
|
<Item partID="ID3" quantity="100" unitPrice="100"/>
|
|
</OrderRequest>
|
|
<ConfirmationRequest confirmID="C1" date="2006-01-02T16:00:00-00:00"
|
|
orderID="OID03" status="accept"/>
|
|
<time date="2006-01-03T00:00:00-00:00"/>
|
|
<time date="2006-01-04T00:00:00-00:00"/>
|
|
<time date="2006-01-05T00:00:00-00:00"/>
|
|
<ShipNotice date="2006-01-05T08:00:00-00:00" orderID="OID01"/>
|
|
<ShipNotice date="2006-01-05T09:00:00-00:00" orderID="OID03"/>
|
|
<time date="2006-01-06T00:00:00-00:00"/>
|
|
<OrderRequest billTo="ACME2" date="2006-01-06T08:00:00-00:00"
|
|
orderID="OID04" total="100" type="new">
|
|
<Item partID="ID2" quantity="10" unitPrice="10"/>
|
|
</OrderRequest>
|
|
<time date="2006-01-07T00:00:00-00:00"/>
|
|
</sequence>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="windowing-queries-results" id=
|
|
"windowing-queries-results"></a>4.2 Queries and Results</h3>
|
|
<div class="div3">
|
|
<h4><a name="windowing_arrange_rows" id=
|
|
"windowing_arrange_rows"></a>4.2.1 Q1</h4>
|
|
<p>Arrange a sequence of items as a table with three columns (using
|
|
as many rows as necessary).</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("arrange_rows.xml");
|
|
|
|
<table>{
|
|
for tumbling window $w in $seq/doc/*
|
|
start at $x when fn:true()
|
|
end at $y when $y - $x = 2
|
|
return
|
|
<tr>{
|
|
for $i in $w
|
|
return
|
|
<td>{data($i)}</td>
|
|
}</tr>
|
|
}</table>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<table>
|
|
<tr>
|
|
<td>Green</td>
|
|
<td>Pink</td>
|
|
<td>Lilac</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Turquoise</td>
|
|
<td>Peach</td>
|
|
<td>Opal</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Champagne</td>
|
|
</tr>
|
|
</table>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_head_para" id=
|
|
"windowing_head_para"></a>4.2.2 Q2</h4>
|
|
<p>Convert a structure with implicit sections to a structure with
|
|
explicit sections.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("head_para.xml");
|
|
|
|
<chapter>{
|
|
for tumbling window $w in $seq/body/*
|
|
start previous $s when $s[self::h2]
|
|
end next $e when $e[self::h2]
|
|
return
|
|
<section title="{data($s)}">{
|
|
for $x in $w
|
|
return
|
|
<para>{data($x)}</para>
|
|
}</section>
|
|
}</chapter>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<chapter>
|
|
<section title="heading1">
|
|
<para>para1</para>
|
|
<para>para2</para>
|
|
</section>
|
|
<section title="heading2">
|
|
<para>para3</para>
|
|
<para>para4</para>
|
|
<para>para5</para>
|
|
</section>
|
|
</chapter>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_term_def_list" id=
|
|
"windowing_term_def_list"></a>4.2.3 Q3</h4>
|
|
<p>Within a glossary in HTML, a defined term <dt> can be
|
|
followed by a definition <dd>. The task is to group these
|
|
together within a <term> element, where a group can consist
|
|
of one or more <dt> elements followed by one or more
|
|
<dd> elements.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("term_def_list.xml");
|
|
|
|
<doc>{
|
|
for tumbling window $w in $seq/doc/*
|
|
start $x when $x[self::dt]
|
|
end $y next $z when $y[self::dd] and $z[self::dt]
|
|
return
|
|
<term>{
|
|
$w
|
|
}</term>
|
|
}</doc>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<doc>
|
|
<term>
|
|
<dt>XML</dt>
|
|
<dd>Extensible Markup Language</dd>
|
|
</term>
|
|
<term>
|
|
<dt>XSLT</dt>
|
|
<dt>XSL Transformations</dt>
|
|
<dd>A language for transforming XML</dd>
|
|
<dd>A specification produced by W3C</dd>
|
|
</term>
|
|
</doc>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_1moving_avarage_time" id=
|
|
"windowing_1moving_avarage_time"></a>4.2.4 Q4</h4>
|
|
<p>Calculate the moving average of temperature values for the 3
|
|
last seconds.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $timesequence := fn:doc("temp_events.xml");
|
|
|
|
let $MAX_DIFF := 2
|
|
|
|
for sliding window $w in $timesequence/stream/event
|
|
start $s_curr at $s_pos previous $s_prev
|
|
when ($s_curr/@time ne $s_prev/@time) or (empty($s_prev))
|
|
only end next $e_next
|
|
when $e_next/@time - $s_curr/@time gt $MAX_DIFF
|
|
return
|
|
avg( $w/@temp )
|
|
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
8 9 17 18
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_2exponential_smoothing_1" id=
|
|
"windowing_2exponential_smoothing_1"></a>4.2.5 Q5</h4>
|
|
<p>Single exponential smoothing (3 last values and smoothing factor
|
|
0.2)</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $timesequence := fn:doc("temp_events.xml");
|
|
let $SMOOTH_CONST := 0.2
|
|
|
|
for sliding window $w in $timesequence/stream/event
|
|
start at $s_pos when true()
|
|
only end at $e_pos when $e_pos - $s_pos eq 2
|
|
return
|
|
round-half-to-even($SMOOTH_CONST * data($w[3]/@temp) + (1 - $SMOOTH_CONST) *
|
|
( $SMOOTH_CONST * data($w[2]/@temp) +
|
|
(1 - $SMOOTH_CONST) * data($w[1]/@temp) ), 2)
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
8.88 8.68 12.32 15.24 23.92
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_3outlier_detection" id=
|
|
"windowing_3outlier_detection"></a>4.2.6 Q6</h4>
|
|
<p>Detect outliers (current value is two times higher (lower) than
|
|
the average of the previous three values) in a sequence of temp
|
|
values.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("temp_events.xml");
|
|
|
|
for sliding window $w in $seq/stream/event
|
|
start $s_curr when fn:true()
|
|
only end next $next when $next/@time > $s_curr/@time + 3
|
|
return
|
|
let $avg := fn:avg($w/@temp)
|
|
where $avg * 2 lt xs:double($next/@temp) or $avg div 2 gt xs:double($next/@temp)
|
|
return <alarm>Outlier detected. Event id:{data($next/@time)}</alarm>
|
|
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<alarm>Outlier detected. Event id:5</alarm>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_1SEQ_A1h" id="windowing_1SEQ_A1h"></a>4.2.7
|
|
Q7</h4>
|
|
<p>Notify when Barbara enters the building within 1 hour after
|
|
Anton</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("mydoc.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $seq/stream/event
|
|
start $s when $s/person eq "Anton" and $s/direction eq "in"
|
|
only end $e next $n when xs:dateTime($n/@time) - xs:dateTime($s/@time) gt
|
|
xs:dayTimeDuration("PT1H")
|
|
or ($e/person eq "Barbara" and $e/direction eq "in")
|
|
or ($e/person eq "Anton" and $e/direction eq "out")
|
|
where $e/person eq "Barbara" and $e/direction eq "in"
|
|
return
|
|
<warning time="{ $e/@time }">Barbara: Anton arrived 1h ago</warning>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<warning time="2006-01-01T11:00:00-00:00">Barbara: Anton arrived 1h ago</warning>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_2SEQ_TimePerPerson" id=
|
|
"windowing_2SEQ_TimePerPerson"></a>4.2.8 Q8</h4>
|
|
<p>Measure the working time of each person</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/stream/event
|
|
start $s when $s/direction eq "in"
|
|
only end $e when $s/person eq $e/person and
|
|
$e/direction eq "out"
|
|
return
|
|
<working-time>
|
|
{$s/person}
|
|
<time>{ xs:dateTime($e/@time) - xs:dateTime($s/@time)}</time>
|
|
</working-time>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<working-time>
|
|
<person>Anton</person>
|
|
<time>PT4H30M</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Barbara</person>
|
|
<time>PT3H</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT1H</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Anton</person>
|
|
<time>PT5H</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT10M</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT5M</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT15M</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT4H15M</time>
|
|
</working-time>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_2SEQ_TimePerPerson_overall" id=
|
|
"windowing_2SEQ_TimePerPerson_overall"></a>4.2.9 Q9</h4>
|
|
<p>Measure the overall working time for each person.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/stream/event
|
|
start $s when $s/direction eq "in"
|
|
only end $e when $s/person eq $e/person and
|
|
$e/direction eq "out"
|
|
let $person := $s/person
|
|
let $workingTime := xs:dateTime($e/@time) - xs:dateTime($s/@time)
|
|
group by $person
|
|
return
|
|
<working-time>
|
|
{$person}
|
|
<time>{ sum($workingTime) }</time>
|
|
</working-time>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<working-time>
|
|
<person>Barbara</person>
|
|
<time>PT3H</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Anton</person>
|
|
<time>PT9H30M</time>
|
|
</working-time>
|
|
<working-time>
|
|
<person>Clara</person>
|
|
<time>PT5H15M</time>
|
|
</working-time>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_3Seq_Not_A" id=
|
|
"windowing_3Seq_Not_A"></a>4.2.10 Q10</h4>
|
|
<p>Display a warning if Barbara does not come to work.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $seq/stream/event[direction eq "in"]
|
|
start $s when fn:true()
|
|
end next $e when xs:date( xs:dateTime($s/@time) ) ne xs:date( xs:dateTime($e/@time) )
|
|
let $date := xs:date(xs:dateTime($s/@time))
|
|
where not($w[person eq "Barbara"])
|
|
return <alert date="{ $date }">Barbara did not come to work</alert>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<alert date="2006-01-02Z">Barbara did not come to work</alert>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_4SEQ_yA" id="windowing_4SEQ_yA"></a>4.2.11
|
|
Q11</h4>
|
|
<p>Identify every person who enters the building before Clara
|
|
withing a 15 minute timeframe (Clara's arrival time - 15
|
|
minutes).</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<results>{
|
|
for tumbling window $w in $seq/stream/event[direction eq "in"]
|
|
start when true()
|
|
only end next $x when $x/person eq "Clara"
|
|
return
|
|
<result time="{ $x/@time }">{
|
|
distinct-values(for $y in $w
|
|
where (xs:dateTime($y/@time) + xs:dayTimeDuration("PT15M") ) ge xs:dateTime($x/@time)
|
|
return $y/person)
|
|
}</result>
|
|
}</results>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<results>
|
|
<result time="2006-01-01T11:15:00-00:00">Barbara</result>
|
|
<result time="2006-01-02T12:00:00-00:00"/>
|
|
<result time="2006-01-02T12:15:00-00:00">Clara</result>
|
|
<result time="2006-01-02T12:25:00-00:00">Clara</result>
|
|
<result time="2006-01-02T14:00:00-00:00"/>
|
|
</results>
|
|
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_5NOSEQ_BothIn" id=
|
|
"windowing_5NOSEQ_BothIn"></a>4.2.12 Q12</h4>
|
|
<p>Notify when both Anton and Barbara enter the office within 30
|
|
minutes of one another.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $seq/stream/event[direction eq "in"]
|
|
start $x when $x/person = ("Barbara", "Anton")
|
|
end next $y when xs:dateTime($y/@time) - xs:dateTime($x/@time) gt xs:dayTimeDuration("PT30M")
|
|
where $w[person eq "Anton"] and $w[person eq "Barbara"]
|
|
return
|
|
<alert date="{ xs:dateTime($y/@time) }">Anton and Barbara just arrived</alert>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<alert time="2006-01-02T14:00:00-00:00">Clara is suspicious</alert>
|
|
</result>
|
|
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_6AGG_Enter_3X_1" id=
|
|
"windowing_6AGG_Enter_3X_1"></a>4.2.13 Q13</h4>
|
|
<p>Inform when a person enters the building at least 3 times within
|
|
1 hour</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("person_events.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/stream/event
|
|
start $s when true()
|
|
end next $e when xs:dateTime($e/@time) - xs:dateTime($s/@time) gt
|
|
xs:dayTimeDuration("PT1H")
|
|
where count($w[person eq $s/person and direction eq "in"]) ge 3
|
|
return
|
|
<alert time="{ $e/@time }">{fn:data($s/person)} is suspicious</alert>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<alert time="2006-01-02T14:00:00-00:00">Clara is suspicious</alert>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_annoying_authors" id=
|
|
"windowing_annoying_authors"></a>4.2.14 Q14</h4>
|
|
<p>Find all annoying authors who have posted three consecutive
|
|
items in the RSS feed.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $rssfeed := fn:doc("rss.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $rssfeed/rss/channel/item
|
|
start $first when fn:true()
|
|
end next $lookAhead when $first/author ne $lookAhead/author
|
|
where count($w) ge 3
|
|
return <annoying-author>{
|
|
$w[1]/author
|
|
}</annoying-author>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<annoying-author>
|
|
<author>rokas@e-mail.de</author>
|
|
</annoying-author>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_interesting_topics" id=
|
|
"windowing_interesting_topics"></a>4.2.15 Q15</h4>
|
|
<p>Every day, provide a list of interesting topics in the RSS feed.
|
|
In our example, interesting means that the title of the item
|
|
contains the specific word XQuery.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $rssfeed := fn:doc("rss.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $rssfeed/rss/channel/item
|
|
start $s_curr when true()
|
|
end next $e_next when
|
|
fn:day-from-dateTime(xs:dateTime($e_next/pubDate)) ne
|
|
fn:day-from-dateTime(xs:dateTime($s_curr/pubDate))
|
|
return
|
|
<item>
|
|
<date>{xs:date(xs:dateTime($s_curr/pubDate))}</date>
|
|
{ for $item in $w
|
|
where fn:contains( xs:string($item/title), 'XQuery')
|
|
return $item/title }
|
|
</item>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<item>
|
|
<date>2003-06-03</date>
|
|
<title>Extending XQuery with Window Functions</title>
|
|
<title>XQueryP: A new programming language is born</title>
|
|
</item>
|
|
<item>
|
|
<date>2003-06-04</date>
|
|
</item>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_summary_by_authors" id=
|
|
"windowing_summary_by_authors"></a>4.2.16 Q16</h4>
|
|
<p>Every day, provide a summary of the RSS feed grouped by
|
|
author.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $rssfeed := fn:doc("rss.xml");
|
|
|
|
<result>{
|
|
for tumbling window $w in $rssfeed/rss/channel/item
|
|
start $s_curr when true()
|
|
end next $e_next when
|
|
fn:day-from-dateTime(xs:dateTime($e_next/pubDate)) ne
|
|
fn:day-from-dateTime(xs:dateTime($s_curr/pubDate))
|
|
return
|
|
<item>
|
|
<date>{xs:date(xs:dateTime($s_curr/pubDate))}</date>
|
|
{ for $a in fn:distinct-values($w/author)
|
|
return
|
|
<author name="{$a}">
|
|
<titles>
|
|
{ $w[author eq $a]/title }
|
|
</titles>
|
|
</author>
|
|
}
|
|
</item>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<item>
|
|
<date>2003-06-03</date>
|
|
<author name="rokas@e-mail.de">
|
|
<titles>
|
|
<title>Why use cases are important Part 1.</title>
|
|
<title>Why use cases are important Part 2.</title>
|
|
<title>Why use cases are important Part 3.</title>
|
|
</titles>
|
|
</author>
|
|
<author name="tim@e-mail.de">
|
|
<titles>
|
|
<title>Extending XQuery with Window Functions</title>
|
|
</titles>
|
|
</author>
|
|
<author name="david@e-mail.de">
|
|
<titles>
|
|
<title>XQueryP: A new programming language is born</title>
|
|
</titles>
|
|
</author>
|
|
</item>
|
|
<item>
|
|
<date>2003-06-04</date>
|
|
<author name="rokas@e-mail.de">
|
|
<titles>
|
|
<title>Why use cases are annoying to write.</title>
|
|
</titles>
|
|
</author>
|
|
</item>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_Q2_most_valuable_customer" id=
|
|
"windowing_Q2_most_valuable_customer"></a>4.2.17 Q17</h4>
|
|
<p>At the end of a day, list the most valuable customers.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("cxml.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/sequence/*
|
|
start $cur previous $prev
|
|
when day-from-dateTime($cur/@date) ne day-from-dateTime($prev/@date) or empty($prev)
|
|
end $end next $next
|
|
when day-from-dateTime(xs:dateTime($end/@date)) ne
|
|
day-from-dateTime(xs:dateTime($next/@date))
|
|
return
|
|
<mostValuableCustomer endOfDay="{xs:dateTime($cur/@date)}">{
|
|
let $companies := for $x in distinct-values($w/@billTo )
|
|
return <amount company="{$x}">{sum($w[@billTo eq $x]/@total)}</amount>
|
|
let $max := max($companies)
|
|
for $company in $companies
|
|
where $company eq xs:untypedAtomic($max)
|
|
return $company
|
|
}</mostValuableCustomer>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<mostValuableCustomer endOfDay="2006-01-01T00:00:00Z">
|
|
<amount company="ACME1">1100</amount>
|
|
</mostValuableCustomer>
|
|
<mostValuableCustomer endOfDay="2006-01-02T00:00:00Z">
|
|
<amount company="ACME1">10000</amount>
|
|
</mostValuableCustomer>
|
|
<mostValuableCustomer endOfDay="2006-01-03T00:00:00Z"/>
|
|
<mostValuableCustomer endOfDay="2006-01-04T00:00:00Z"/>
|
|
<mostValuableCustomer endOfDay="2006-01-05T00:00:00Z"/>
|
|
<mostValuableCustomer endOfDay="2006-01-06T00:00:00Z">
|
|
<amount company="ACME2">100</amount>
|
|
</mostValuableCustomer>
|
|
<mostValuableCustomer endOfDay="2006-01-07T00:00:00Z"/>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_Q3_transaction_time" id=
|
|
"windowing_Q3_transaction_time"></a>4.2.18 Q18</h4>
|
|
<p>Calculate the time needed to process an order from the request
|
|
up to the shipping.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("cxml.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/sequence/*
|
|
start $s when $s[self::OrderRequest]
|
|
end $e when $e/@orderID eq $s/@orderID and
|
|
$e[self::ConfirmationRequest] and $e/@status eq "reject"
|
|
or $e[self::ShipNotice]
|
|
where $e[self::ShipNotice]
|
|
return
|
|
<timeToShip orderID="{ $s/@orderID}">{xs:dateTime($e/@date) - xs:dateTime($s/@date) }</timeToShip>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<timeToShip orderID="OID01">P3DT22H</timeToShip>
|
|
<timeToShip orderID="OID03">P2DT19H</timeToShip>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="windowing_Q4_ship_together" id=
|
|
"windowing_Q4_ship_together"></a>4.2.19 Q19</h4>
|
|
<p>At the moment of the shipping notification, calculate if an open
|
|
request exists that can be shipped to the same address.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("cxml.xml");
|
|
|
|
<result>{
|
|
for sliding window $w in $seq/sequence/*
|
|
start previous $wSPrev when $wSPrev[self::OrderRequest]
|
|
end next $wENext when $wENext/@orderID eq $wSPrev/@orderID and
|
|
( $wENext[self::ConfirmationRequest] and $wENext/@status eq "reject")
|
|
or $wENext[self::ShipNotice]
|
|
where $wENext[self::ShipNotice]
|
|
return
|
|
<bundleWith orderId="{$wSPrev/@orderID}">{
|
|
for sliding window $bundle in $w
|
|
start $bSCur
|
|
when $bSCur[self::OrderRequest] and $bSCur/@shipTo eq $wSPrev/@shipTo
|
|
end $bECur next $bENext
|
|
when $bECur/@orderID eq $bSCur/@orderID
|
|
and ($bECur[self::ConfirmationRequest] and $bECur/@status eq "reject")
|
|
or $bECur[self::ShipNotice]
|
|
where empty($bENext)
|
|
return $bSCur
|
|
}</bundleWith>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<bundleWith orderId="OID01">
|
|
<OrderRequest billTo="ACME1" date="2006-01-02T14:00:00-00:00"
|
|
orderID="OID03" shipTo="ACME1" total="10000" type="new">
|
|
<Item partID="ID3" quantity="100" unitPrice="100"/>
|
|
</OrderRequest>
|
|
</bundleWith>
|
|
<bundleWith orderId="OID03"/>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="count-use-cases" id="count-use-cases"></a>5 Use Case
|
|
"Count" - Queries which require output numbering</h2>
|
|
<p>The described queries in this section all require tuple
|
|
numbering. The numbering is either required in the final result or
|
|
might also be required at some point in the middle when the tuple
|
|
stream gets generated.</p>
|
|
<div class="div2">
|
|
<h3><a name="d2e942" id="d2e942"></a>5.1 Schema and Sample
|
|
Data</h3>
|
|
<p>The "Count" use cases are all based on the shopping scenario
|
|
which can be found in the section <a href="#data">Shopping Scenario
|
|
Schema and Data</a>.</p>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="d2e950" id="d2e950"></a>5.2 Queries and Results</h3>
|
|
<div class="div3">
|
|
<h4><a name="count-numbering" id="count-numbering"></a>5.2.1
|
|
Q1</h4>
|
|
<p>List all products in alphabatical order with a continously
|
|
increasing number.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<products>{
|
|
for $product in doc("products.xml")/*/product
|
|
order by $product/name
|
|
count $number
|
|
return
|
|
<product number="{$number}">{$product/*}</product>
|
|
}</products>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<products>
|
|
<product number="1">
|
|
<name>blender</name>
|
|
<category>kitchen</category>
|
|
<price>50</price>
|
|
<cost>25</cost>
|
|
</product>
|
|
<product number="2">
|
|
<name>broiler</name>
|
|
<category>kitchen</category>
|
|
<price>100</price>
|
|
<cost>70</cost>
|
|
</product>
|
|
<product number="3">
|
|
<name>shirt</name>
|
|
<category>clothes</category>
|
|
<price>10</price>
|
|
<cost>3</cost>
|
|
</product>
|
|
<product number="4">
|
|
<name>socks</name>
|
|
<category>clothes</category>
|
|
<price>5</price>
|
|
<cost>2</cost>
|
|
</product>
|
|
<product number="5">
|
|
<name>toaster</name>
|
|
<category>kitchen</category>
|
|
<price>30</price>
|
|
<cost>10</cost>
|
|
</product>
|
|
</products>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="count-windowing" id="count-windowing"></a>5.2.2
|
|
Q2</h4>
|
|
<p>Arrange a sequence of items as a table with three columns (using
|
|
as many rows as necessary) like in <a href=
|
|
"#windowing_arrange_rows">Q1</a> from the windowing use
|
|
cases.Additionally, number every row continuously.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare variable $seq := fn:doc("arrange_rows.xml");
|
|
|
|
<table>{
|
|
for tumbling window $w in $seq/doc/*
|
|
start at $x when fn:true()
|
|
end at $y when $y - $x = 2
|
|
count $rowNumber
|
|
return
|
|
<tr>
|
|
<td>{$rowNumber}</td>{
|
|
for $i in $w
|
|
return
|
|
<td>{data($i)}</td>
|
|
}</tr>
|
|
}</table>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<table>
|
|
<tr>
|
|
<td>1</td>
|
|
<td>Green</td>
|
|
<td>Pink</td>
|
|
<td>Lilac</td>
|
|
</tr>
|
|
<tr>
|
|
<td>2</td>
|
|
<td>Turquoise</td>
|
|
<td>Peach</td>
|
|
<td>Opal</td>
|
|
</tr>
|
|
<tr>
|
|
<td>3</td>
|
|
<td>Champagne</td>
|
|
</tr>
|
|
</table>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="count-top-k" id="count-top-k"></a>5.2.3 Q3</h4>
|
|
<p>Top-K query: Return the three best-selling products (by
|
|
quantity).</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $sales in doc("sales-records.xml")/*/record
|
|
let $name := $sales/product-name
|
|
group by $name
|
|
let $qty := sum($sales/qty)
|
|
order by $qty descending
|
|
count $count
|
|
where $count <= 3
|
|
return
|
|
<sale product="{$name}" qty="{$qty }"/>
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<sale product="socks" qty="510"/>
|
|
<sale product="blender" qty="250"/>
|
|
<sale product="toaster" qty="200"/>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="outer-join-uc" id="outer-join-uc"></a>6 Use Case
|
|
"Outer For" - Queries which require outer joins</h2>
|
|
<p>This use case demonstrate how the new "outer for" clause can
|
|
help to express outer joins in XQuery.</p>
|
|
<div class="div2">
|
|
<h3><a name="d2e1025" id="d2e1025"></a>6.1 Schema and Sample
|
|
Data</h3>
|
|
<p>The "Outer For" use case is based on the shopping scenario which
|
|
can be found in the section <a href="#data">Shopping Scenario
|
|
Schema and Data</a>.</p>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="d2e1033" id="d2e1033"></a>6.2 Queries and Results</h3>
|
|
<div class="div3">
|
|
<h4><a name="outer-join-1" id="outer-join-1"></a>6.2.1 Q1</h4>
|
|
<p>Report all the store sales including stores which have not sold
|
|
anything.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $store in doc("stores.xml")/*/store
|
|
for $sale allowing empty in doc("sales-records.xml")/*/record[
|
|
store-number eq $store/store-number]
|
|
return
|
|
<store number="{$store/store-number}"
|
|
product="{$sale/product-name}"
|
|
state="{$store/state}"
|
|
sold="{$sale/qty}" />
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>
|
|
<store number="1" state="CA" product="broiler" sold="20"/>
|
|
<store number="1" state="CA" product="socks" sold="500"/>
|
|
<store number="2" state="CA" product="toaster" sold="100"/>
|
|
<store number="2" state="CA" product="toaster" sold="50"/>
|
|
<store number="2" state="CA" product="socks" sold="10"/>
|
|
<store number="3" state="MA" product="toaster" sold="50"/>
|
|
<store number="3" state="MA" product="blender" sold="100"/>
|
|
<store number="3" state="MA" product="blender" sold="150"/>
|
|
<store number="3" state="MA" product="shirt" sold="10"/>
|
|
<store number="4" state="WA" product="" sold=""/>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="simplified-flwor-2" id="simplified-flwor-2"></a>6.2.2
|
|
Q2</h4>
|
|
<p>List all the sales records. Include also all the items which
|
|
were not sold in a store.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $store in doc("stores.xml")/*/store
|
|
for $product in doc("products.xml")/*/product
|
|
for $sale allowing empty in doc("sales-records.xml")/*/record[
|
|
store-number eq $store/store-number and
|
|
product-name eq $product/name]
|
|
return
|
|
<store number="{$store/store-number}"
|
|
state="{$store/state}"
|
|
product="{$sale/product-name}"
|
|
sold="{$sale/qty}" />
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<result>
|
|
<store number="1" state="CA" product="broiler" sold="20"/>
|
|
<store number="1" state="CA" product="toaster" sold=""/>
|
|
<store number="1" state="CA" product="blender" sold=""/>
|
|
<store number="1" state="CA" product="socks" sold="500"/>
|
|
<store number="1" state="CA" product="shirt" sold=""/>
|
|
<store number="2" state="CA" product="broiler" sold=""/>
|
|
<store number="2" state="CA" product="toaster" sold="100"/>
|
|
<store number="2" state="CA" product="toaster" sold="50"/>
|
|
<store number="2" state="CA" product="blender" sold=""/>
|
|
<store number="2" state="CA" product="socks" sold="10"/>
|
|
<store number="2" state="CA" product="shirt" sold=""/>
|
|
<store number="3" state="CA" product="broiler" sold=""/>
|
|
<store number="3" state="MA" product="toaster" sold="50"/>
|
|
<store number="3" state="MA" product="blender" sold="100"/>
|
|
<store number="3" state="MA" product="blender" sold="150"/>
|
|
<store number="3" state="MA" product="socks" sold=""/>
|
|
<store number="3" state="MA" product="shirt" sold="10"/>
|
|
<store number="4" state="MA" product="broiler" sold=""/>
|
|
<store number="4" state="MA" product="toaster" sold=""/>
|
|
<store number="4" state="MA" product="blender" sold=""/>
|
|
<store number="4" state="MA" product="socks" sold=""/>
|
|
<store number="4" state="MA" product="shirt" sold=""/>
|
|
</result>
|
|
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="try-catch-use-cases" id="try-catch-use-cases"></a>7
|
|
Use Case "Try-Catch" - Queries which require to recover from
|
|
errors</h2>
|
|
<p>This use case covers queries that require to recover from
|
|
errors.</p>
|
|
<div class="div2">
|
|
<h3><a name="dataerrorproducts" id="dataerrorproducts"></a>7.1
|
|
Sample Data</h3>
|
|
<p>Q1 and Q2 are based on a errornous version of product.xml from
|
|
<a href="#data">Shopping Scenario Schema and Data</a>, whereas Q3
|
|
does not require any input data. Sample data for Q1 and Q2 named
|
|
product-err.xml are shown below:</p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<products>
|
|
<product>
|
|
<name>broiler</name>
|
|
<category>kitchen</category>
|
|
<price>100</price>
|
|
<cost>"70"</cost>
|
|
</product>
|
|
<product>
|
|
<name>toaster</name>
|
|
<category>kitchen</category>
|
|
<price>30</price>
|
|
<cost>10</cost>
|
|
</product>
|
|
<product>
|
|
<name>blender</name>
|
|
<category>kitchen</category>
|
|
<price>50</price>
|
|
<cost>25</cost>
|
|
</product>
|
|
<product>
|
|
<name>socks</name>
|
|
<category>clothes</category>
|
|
<price>5</price>
|
|
<cost>2</cost>
|
|
</product>
|
|
<product>
|
|
<name>shirt</name>
|
|
<category>clothes</category>
|
|
<price>10</price>
|
|
<cost>3</cost>
|
|
</product>
|
|
</products>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="d2e1096" id="d2e1096"></a>7.2 Queries and Results</h3>
|
|
<div class="div3">
|
|
<h4><a name="try-catch-1" id="try-catch-1"></a>7.2.1 Q1</h4>
|
|
<p>Calculate the margin of every product. If an error occurs,
|
|
report a user-friendly message.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
try {
|
|
<result>{
|
|
for $product in fn:doc("product-err.xml")//product
|
|
return
|
|
<product>{$product/name}
|
|
<margin>{$product/price - $product/cost}</margin>
|
|
</product>
|
|
}</result>
|
|
} catch * {
|
|
"An error occured, please ask your consultant for help."
|
|
}
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
An error occured, please ask your consultant for help.
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="try-catch-2" id="try-catch-2"></a>7.2.2 Q2</h4>
|
|
<p>Report the margin in procent of every product. If an error
|
|
occurs the failure should be listed, but the query should still
|
|
continue to report the other values.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<result>{
|
|
for $product in fn:doc("product-err.xml")//product
|
|
return
|
|
try {
|
|
<product>{$product/name}
|
|
<margin>{$product/price div $product/cost}</margin>
|
|
</product>
|
|
} catch * ($errcode) {
|
|
<product>{
|
|
($product/name, "Error:", $errcode)
|
|
}</product>
|
|
}
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<result>
|
|
<product>
|
|
<name>broiler</name>
|
|
Error: FORG0001
|
|
</product>
|
|
<product>
|
|
<name>toaster</name>
|
|
<margin>3</margin>
|
|
</product>
|
|
<product>
|
|
<name>blender</name>
|
|
<margin>2</margin>
|
|
</product>
|
|
<product>
|
|
<name>socks</name>
|
|
<margin>2.5</margin>
|
|
</product>
|
|
<product>
|
|
<name>shirt</name>
|
|
<margin>3.3333333333333333</margin>
|
|
</product>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
<div class="div3">
|
|
<h4><a name="try-catch-3" id="try-catch-3"></a>7.2.3 Q3</h4>
|
|
<p>For a sequence of inputs the n-th fibonacci number has to be
|
|
calculated using a pre-defined function. The function is built to
|
|
avoid long running times and therefore rejects high values by
|
|
throwing a user-defined error. If such an error occurs during
|
|
calculation, a warning should be displayed, but the processing
|
|
should continue.</p>
|
|
<p><em>Solution in XQuery:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
declare namespace foo='http://foo.com';
|
|
declare function local:fib-recur($n as xs:integer) as xs:integer? {
|
|
if ($n <0) then ()
|
|
else if ($n > 100) then
|
|
fn:error(fn:QName('http://foo.com', 'ValueToBig'), 'Value too big')
|
|
else if ($n = 0) then 0
|
|
else if ($n=1) then 1
|
|
else local:fib-recur($n - 1) + local:fib-recur($n - 2)
|
|
};
|
|
|
|
<result>{
|
|
for $x in (3,1,1030,5)
|
|
return
|
|
try{
|
|
<fib input="{$x}">{local:fib-recur($x)}</fib>
|
|
}catch foo:ValueToBig {
|
|
<fib input="{$x}">Number to big</fib>
|
|
}
|
|
}</result>
|
|
</pre></div>
|
|
<p><em>Expected Result:</em></p>
|
|
<div class="exampleInner">
|
|
<pre>
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<result>
|
|
<fib input="3">2</fib>
|
|
<fib input="1">1</fib>
|
|
<fib input="1030">Number to big</fib>
|
|
<fib input="5">5</fib>
|
|
</result>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="back">
|
|
<div class="div1">
|
|
<h2><a name="acknowledgements" id="acknowledgements"></a>A
|
|
Acknowledgements (Non-Normative)</h2>
|
|
<p>The Working Group thanks the following individuals for their
|
|
contributions:</p>
|
|
<table border="1">
|
|
<tbody>
|
|
<tr>
|
|
<td>Peter M. Fischer, Donald Kossmann, Rokas Tamosevicius</td>
|
|
<td>Use Case "windowing"</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Use case "windowing" has been previously published in <a href=
|
|
"#Fischer2006">[Windowing UC]</a>.</p>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="ChangeLog" id="ChangeLog"></a>B Change Log
|
|
(Non-Normative)</h2>
|
|
<div class="div2">
|
|
<h3><a name="id-2008-01-30" id="id-2008-01-30"></a>B.1 30 January
|
|
2008</h3>
|
|
<ul>
|
|
<li>
|
|
<p>Added group-by UC.</p>
|
|
</li>
|
|
<li>
|
|
<p>Added windowing UC.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="div2">
|
|
<h3><a name="id-2008-11-17" id="id-2008-11-17"></a>B.2 17 November
|
|
2008</h3>
|
|
<ul>
|
|
<li>
|
|
<p>Added try-catch UC.</p>
|
|
</li>
|
|
<li>
|
|
<p>Added outer-join UC.</p>
|
|
</li>
|
|
<li>
|
|
<p>Added output-numbering UC.</p>
|
|
</li>
|
|
<li>
|
|
<p>Changed all DTDs to XML Schema.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="div1">
|
|
<h2><a name="references" id="references"></a>C References
|
|
(Non-Normative)</h2>
|
|
<p>The following references are some of the works considered by the
|
|
WG in deriving its use cases.</p>
|
|
<dl>
|
|
<dt class="label"><span><a name="Fischer2006" id=
|
|
"Fischer2006"></a>Windowing UC</span></dt>
|
|
<dd>
|
|
<div><a href=
|
|
"http://www.dbis.ethz.ch/research/publications/XQWindowsUseCases.pdf">
|
|
<cite>Windows for XQuery - Use Cases</cite></a>, Peter M. Fischer,
|
|
Donald Kossmann, Tim Kraska and Rokas Tamosevicius, 2006, Technical
|
|
Report, ETH Zurich</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xmlschema-0" id=
|
|
"xmlschema-0"></a>XMLSchema0</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xmlschema-0/"><cite>XML Schema
|
|
Part 0: Primer Second Edition</cite></a>, Priscilla Walmsley and
|
|
David C. Fallside, Editors. World Wide Web Consortium,
|
|
28 Oct 2004. This version is
|
|
http://www.w3.org/TR/2004/REC-xmlschema-0-20041028/. The <a href=
|
|
"http://www.w3.org/TR/xmlschema-0/">latest version</a> is available
|
|
at http://www.w3.org/TR/xmlschema-0/.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xmlschema-1" id=
|
|
"xmlschema-1"></a>XMLSchema1</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xmlschema-1/"><cite>XML Schema
|
|
Part 1: Structures Second Edition</cite></a>, David Beech, Henry S.
|
|
Thompson, Murray Maloney, and Noah Mendelsohn, Editors. World Wide
|
|
Web Consortium, 28 Oct 2004. This version is
|
|
http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/. The <a href=
|
|
"http://www.w3.org/TR/xmlschema-1/">latest version</a> is available
|
|
at http://www.w3.org/TR/xmlschema-1/.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xmlschema-2" id=
|
|
"xmlschema-2"></a>XMLSchema2</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xmlschema-2/"><cite>XML Schema
|
|
Part 2: Datatypes Second Edition</cite></a>, Ashok Malhotra and
|
|
Paul V. Biron, Editors. World Wide Web Consortium,
|
|
28 Oct 2004. This version is
|
|
http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/. The <a href=
|
|
"http://www.w3.org/TR/xmlschema-2/">latest version</a> is available
|
|
at http://www.w3.org/TR/xmlschema-2/.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xquery-30" id=
|
|
"xquery-30"></a>XQuery 3.0</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xquery-30/"><cite>XQuery 3.0: An
|
|
XML Query Language</cite></a>, Jonathan Robie, Don Chamberlin,
|
|
Michael Dyck, John Snelson, Editors. World Wide Web Consortium, 14
|
|
December 2010. This version is
|
|
http://www.w3.org/TR/2010/WD-xquery-30-20101214/. The <a href=
|
|
"http://www.w3.org/TR/xquery-30/">latest version</a> is available
|
|
at http://www.w3.org/TR/xquery-30/.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xquery-30-requirements" id=
|
|
"xquery-30-requirements"></a>XQuery 3.0 Requirements</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xquery-30-requirements/">XML
|
|
Query (XQuery) 3.0 Requirements</a>, W3C Working Draft, 16
|
|
September 2010.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="xslt-30" id="xslt-30"></a>XSLT
|
|
3.0</span></dt>
|
|
<dd>
|
|
<div><a href="http://www.w3.org/TR/xslt-30/"><cite>XSL
|
|
Transformations (XSLT) Version 3.0</cite></a> (expected), Michael
|
|
Kay, Editor. World Wide Web Consortium, 14 December 2010. This
|
|
version is http://www.w3.org/TR/2010/WD-xslt-30-20101214/. The
|
|
<a href="http://www.w3.org/TR/xslt-30/">latest version</a> is
|
|
available at http://www.w3.org/TR/xslt-30/.</div>
|
|
</dd>
|
|
<dt class="label"><span><a name="UseCaseQueries" id=
|
|
"UseCaseQueries"></a>Use Case Sample Queries</span></dt>
|
|
<dd>
|
|
<div><a href=
|
|
"http://www.w3.org/2010/12/xquery-30-use-cases/xquery-30-use-case-queries.txt">
|
|
<cite>Queries from this document</cite></a>, presented in a single
|
|
file</div>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|