Find the % change in monthly sales, each month
+ +
+ SELECT A.Month, (A.Sales-B.Sales) / B.Sales
+ FROM (SELECT … AS Month, SUM(…) AS Sales FROM …) A,
+ (SELECT … AS Month, SUM(…) AS Sales FROM …) B
+ WHERE A.Month = B.Month + 1
+
+ Find the % change in monthly sales, each month
+ + +Find the daily top-5 products by sales in the last week
+ +
+ SELECT Product, SUM(…) AS Sales FROM … WHERE date = today - 1
+ ORDER BY Sales Desc LIMIT 5 UNION ALL
+ SELECT Product, SUM(…) AS Sales FROM … WHERE date = today - 2
+ ORDER BY Sales Desc LIMIT 5 UNION ALL …
+
+ Find the trailing n-day moving average of sales
+ +… almost impossible to express if n is a parameter
(i.e., query size depends on N)
WINDOW
Operator
+ SELECT L.state, T.month,
+ AVG(S.sales) OVER W as movavg
+ FROM Sales S, Times T, Locations L
+ WHERE S.timeid = T.timeid
+ AND S.locid = L.locid
+ WINDOW W AS (
+ PARTITION BY L.state
+ ORDER BY T.month
+ RANGE BETWEEN INTERVAL ‘1’ MONTH PRECEDING
+ AND INTERVAL ‘1’ MONTH FOLLOWING
+ )
+
+ PARTITION BY
GROUP BY
ORDER BY
RANGE BETWEEN ... AND ...
[Aggregate] OVER [WindowName]
Challenge: Need to react to new data as it arrives
+Idea 1: Mandate ONLY WINDOW
queries
Idea 2: Index the buffer!
+ +Challenge: Maintaining the index as tuples fall out of the buffer
+Tuples always enter from one side and exit out the other
+Lots of lookups for active tuples.
+$O(1 + log(|W|))$ insertions.
+$O(1 + log(|W|))$ expiration.
+WINDOW
joins.