window-functions-example-table.html 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <!--
  2. To render properly, keep the left-hand alignment of the table
  3. -->
  4. <table>
  5. <thead>
  6. <tr>
  7. <th></th>
  8. <th>Idiomatic Materialize SQL</th>
  9. </tr>
  10. </thead>
  11. <tbody>
  12. <tr>
  13. <td>Top-K over partition<br>(K >= 1)</td>
  14. <td class="copyableCode">
  15. ```mzsql
  16. SELECT order_id, item, subtotal
  17. FROM (SELECT DISTINCT order_id FROM orders_view) grp,
  18. LATERAL (SELECT item, subtotal FROM orders_view
  19. WHERE order_id = grp.order_id
  20. ORDER BY subtotal DESC LIMIT 3) -- For Top 3
  21. ORDER BY order_id, subtotal DESC;
  22. ```
  23. </td>
  24. </tr>
  25. <tr>
  26. <td>Top-K over partition<br>(K = 1)</td>
  27. <td class="copyableCode">
  28. ```mzsql
  29. SELECT DISTINCT ON(order_id) order_id, item, subtotal
  30. FROM orders_view
  31. ORDER BY order_id, subtotal DESC; -- For Top 1
  32. ```
  33. </td>
  34. </tr>
  35. <tr>
  36. <td>First value over partition<br>order by ...</td>
  37. <td class="copyableCode">
  38. ```mzsql
  39. SELECT o.order_id, minmax.lowest_price, minmax.highest_price,
  40. o.item,
  41. o.price,
  42. o.price - minmax.lowest_price AS diff_lowest_price,
  43. o.price - minmax.highest_price AS diff_highest_price
  44. FROM orders_view o,
  45. (SELECT order_id,
  46. MIN(price) AS lowest_price,
  47. MAX(price) AS highest_price
  48. FROM orders_view
  49. GROUP BY order_id) minmax
  50. WHERE o.order_id = minmax.order_id
  51. ORDER BY o.order_id, o.item;
  52. ```
  53. </td>
  54. </tr>
  55. <tr>
  56. <td>Last value over partition<br>order by...<br>range between unbounded preceding<br>and unbounded following</td>
  57. <td class="copyableCode">
  58. ```mzsql
  59. SELECT o.order_id, minmax.lowest_price, minmax.highest_price,
  60. o.item,
  61. o.price,
  62. o.price - minmax.lowest_price AS diff_lowest_price,
  63. o.price - minmax.highest_price AS diff_highest_price
  64. FROM orders_view o,
  65. (SELECT order_id,
  66. MIN(price) AS lowest_price,
  67. MAX(price) AS highest_price
  68. FROM orders_view
  69. GROUP BY order_id) minmax
  70. WHERE o.order_id = minmax.order_id
  71. ORDER BY o.order_id, o.item;
  72. ```
  73. </td>
  74. </tr>
  75. <tr>
  76. <td>
  77. Lag over (order by) whose ordering can be represented by some equality
  78. condition.
  79. </td>
  80. <td class="copyableCode">
  81. ***If suppressing the first row since it has no previous row***
  82. ```mzsql
  83. SELECT o1.order_date, o1.daily_total,
  84. o2.daily_total as previous_daily_total
  85. FROM orders_daily_totals o1, orders_daily_totals o2
  86. WHERE o1.order_date = o2.order_date + INTERVAL '1' DAY
  87. ORDER BY order_date;
  88. ```
  89. ***To include the first row***
  90. ```mzsql
  91. SELECT o1.order_date, o1.daily_total,
  92. o2.daily_total as previous_daily_total
  93. FROM orders_daily_totals o1
  94. LEFT JOIN orders_daily_totals o2
  95. ON o1.order_date = o2.order_date + INTERVAL '1' DAY
  96. ORDER BY order_date;
  97. ```
  98. </td>
  99. </tr>
  100. <tr>
  101. <td>
  102. Lead over (order by) whose ordering can be represented by some equality
  103. condition.
  104. </td>
  105. <td class="copyableCode">
  106. ***To suppress the last row since it has no next row***
  107. ```mzsql
  108. SELECT o1.order_date, o1.daily_total,
  109. o2.daily_total as previous_daily_total
  110. FROM orders_daily_totals o1, orders_daily_totals o2
  111. WHERE o1.order_date = o2.order_date - INTERVAL '1' DAY
  112. ORDER BY order_date;
  113. ```
  114. ***To include the last row***
  115. ```mzsql
  116. SELECT o1.order_date, o1.daily_total,
  117. o2.daily_total as previous_daily_total
  118. FROM orders_daily_totals o1
  119. LEFT JOIN orders_daily_totals o2
  120. ON o1.order_date = o2.order_date - INTERVAL '1' DAY
  121. ORDER BY order_date;
  122. ```
  123. </td>
  124. </tr>
  125. </tbody>
  126. </table>
  127. <!--
  128. To render properly, keep the left-hand alignment of table
  129. -->