Window Clauses

XQuery 3.0 added windows over ordered sequences. A tumbling window cuts the sequence into non-overlapping pieces; a sliding window starts a new window at every item, so windows overlap. Each window has a start condition and an optional end condition, which can bind the current item, its position (at), and the previous and next items. only end drops a final window whose end condition never became true:

window.xq: daily totals and a three-order moving average
(: Daily totals with a tumbling window, a 3-order moving average with a sliding window :)
let $orders := doc("orders.xml")//order
return (
  for tumbling window $w in $orders
      start $s when true() end next $n when $n/@date ne $s/@date
  return $s/@date || ": " || count($w) || " order(s), " || sum($w/@qty) || " units",
  for sliding window $w in $orders
      start at $i when true() only end at $j when $j - $i eq 2
  return $w[1]/@id || "-" || $w[3]/@id || ": average quantity " || round(avg($w/@qty), 2)
)
Running the window queries
xquery window.xq
Output
"2026-09-28: 2 order(s), 3 units"
"2026-09-29: 3 order(s), 6 units"
"2026-09-30: 2 order(s), 3 units"
"2026-10-01: 1 order(s), 1 units"
"o1001-o1003: average quantity 2"
"o1002-o1004: average quantity 1.67"
"o1003-o1005: average quantity 2"
"o1004-o1006: average quantity 1.67"
"o1005-o1007: average quantity 1.67"
"o1006-o1008: average quantity 1.33"

The tumbling window ends just before the next order has a new date, so each window is one day, the XML equivalent of a session or batch boundary in an event stream. The sliding window with only end yields exactly the six complete three-order windows, the same idea as a SQL window frame (Analytical SQL and Data Warehouses) or a Kafka Streams 129 hopping window (Apache Kafka and Managed Cloud Kafka).