gooderp18绿色标准版
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.

202 lines
12KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.5. Window Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="tutorial-transactions.html" title="3.4. Transactions" /><link rel="next" href="tutorial-inheritance.html" title="3.6. Inheritance" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.5. Window Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-transactions.html" title="3.4. Transactions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-inheritance.html" title="3.6. Inheritance">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="TUTORIAL-WINDOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.5. Window Functions</h2></div></div></div><a id="id-1.4.5.6.2" class="indexterm"></a><p>
  3. A <em class="firstterm">window function</em> performs a calculation across a set of
  4. table rows that are somehow related to the current row. This is comparable
  5. to the type of calculation that can be done with an aggregate function.
  6. However, window functions do not cause rows to become grouped into a single
  7. output row like non-window aggregate calls would. Instead, the
  8. rows retain their separate identities. Behind the scenes, the window
  9. function is able to access more than just the current row of the query
  10. result.
  11. </p><p>
  12. Here is an example that shows how to compare each employee's salary
  13. with the average salary in his or her department:
  14. </p><pre class="programlisting">
  15. SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
  16. </pre><p>
  17. </p><pre class="screen">
  18. depname | empno | salary | avg
  19. -----------+-------+--------+-----------------------
  20. develop | 11 | 5200 | 5020.0000000000000000
  21. develop | 7 | 4200 | 5020.0000000000000000
  22. develop | 9 | 4500 | 5020.0000000000000000
  23. develop | 8 | 6000 | 5020.0000000000000000
  24. develop | 10 | 5200 | 5020.0000000000000000
  25. personnel | 5 | 3500 | 3700.0000000000000000
  26. personnel | 2 | 3900 | 3700.0000000000000000
  27. sales | 3 | 4800 | 4866.6666666666666667
  28. sales | 1 | 5000 | 4866.6666666666666667
  29. sales | 4 | 4800 | 4866.6666666666666667
  30. (10 rows)
  31. </pre><p>
  32. The first three output columns come directly from the table
  33. <code class="structname">empsalary</code>, and there is one output row for each row in the
  34. table. The fourth column represents an average taken across all the table
  35. rows that have the same <code class="structfield">depname</code> value as the current row.
  36. (This actually is the same function as the non-window <code class="function">avg</code>
  37. aggregate, but the <code class="literal">OVER</code> clause causes it to be
  38. treated as a window function and computed across the window frame.)
  39. </p><p>
  40. A window function call always contains an <code class="literal">OVER</code> clause
  41. directly following the window function's name and argument(s). This is what
  42. syntactically distinguishes it from a normal function or non-window
  43. aggregate. The <code class="literal">OVER</code> clause determines exactly how the
  44. rows of the query are split up for processing by the window function.
  45. The <code class="literal">PARTITION BY</code> clause within <code class="literal">OVER</code>
  46. divides the rows into groups, or partitions, that share the same
  47. values of the <code class="literal">PARTITION BY</code> expression(s). For each row,
  48. the window function is computed across the rows that fall into the
  49. same partition as the current row.
  50. </p><p>
  51. You can also control the order in which rows are processed by
  52. window functions using <code class="literal">ORDER BY</code> within <code class="literal">OVER</code>.
  53. (The window <code class="literal">ORDER BY</code> does not even have to match the
  54. order in which the rows are output.) Here is an example:
  55. </p><pre class="programlisting">
  56. SELECT depname, empno, salary,
  57. rank() OVER (PARTITION BY depname ORDER BY salary DESC)
  58. FROM empsalary;
  59. </pre><p>
  60. </p><pre class="screen">
  61. depname | empno | salary | rank
  62. -----------+-------+--------+------
  63. develop | 8 | 6000 | 1
  64. develop | 10 | 5200 | 2
  65. develop | 11 | 5200 | 2
  66. develop | 9 | 4500 | 4
  67. develop | 7 | 4200 | 5
  68. personnel | 2 | 3900 | 1
  69. personnel | 5 | 3500 | 2
  70. sales | 1 | 5000 | 1
  71. sales | 4 | 4800 | 2
  72. sales | 3 | 4800 | 2
  73. (10 rows)
  74. </pre><p>
  75. As shown here, the <code class="function">rank</code> function produces a numerical rank
  76. for each distinct <code class="literal">ORDER BY</code> value in the current row's
  77. partition, using the order defined by the <code class="literal">ORDER BY</code> clause.
  78. <code class="function">rank</code> needs no explicit parameter, because its behavior
  79. is entirely determined by the <code class="literal">OVER</code> clause.
  80. </p><p>
  81. The rows considered by a window function are those of the <span class="quote">“<span class="quote">virtual
  82. table</span>”</span> produced by the query's <code class="literal">FROM</code> clause as filtered by its
  83. <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>, and <code class="literal">HAVING</code> clauses
  84. if any. For example, a row removed because it does not meet the
  85. <code class="literal">WHERE</code> condition is not seen by any window function.
  86. A query can contain multiple window functions that slice up the data
  87. in different ways using different <code class="literal">OVER</code> clauses, but
  88. they all act on the same collection of rows defined by this virtual table.
  89. </p><p>
  90. We already saw that <code class="literal">ORDER BY</code> can be omitted if the ordering
  91. of rows is not important. It is also possible to omit <code class="literal">PARTITION
  92. BY</code>, in which case there is a single partition containing all rows.
  93. </p><p>
  94. There is another important concept associated with window functions:
  95. for each row, there is a set of rows within its partition called its
  96. <em class="firstterm">window frame</em>. Some window functions act only
  97. on the rows of the window frame, rather than of the whole partition.
  98. By default, if <code class="literal">ORDER BY</code> is supplied then the frame consists of
  99. all rows from the start of the partition up through the current row, plus
  100. any following rows that are equal to the current row according to the
  101. <code class="literal">ORDER BY</code> clause. When <code class="literal">ORDER BY</code> is omitted the
  102. default frame consists of all rows in the partition.
  103. <a href="#ftn.id-1.4.5.6.9.5" class="footnote"><sup class="footnote" id="id-1.4.5.6.9.5">[4]</sup></a>
  104. Here is an example using <code class="function">sum</code>:
  105. </p><pre class="programlisting">
  106. SELECT salary, sum(salary) OVER () FROM empsalary;
  107. </pre><pre class="screen">
  108. salary | sum
  109. --------+-------
  110. 5200 | 47100
  111. 5000 | 47100
  112. 3500 | 47100
  113. 4800 | 47100
  114. 3900 | 47100
  115. 4200 | 47100
  116. 4500 | 47100
  117. 4800 | 47100
  118. 6000 | 47100
  119. 5200 | 47100
  120. (10 rows)
  121. </pre><p>
  122. Above, since there is no <code class="literal">ORDER BY</code> in the <code class="literal">OVER</code>
  123. clause, the window frame is the same as the partition, which for lack of
  124. <code class="literal">PARTITION BY</code> is the whole table; in other words each sum is
  125. taken over the whole table and so we get the same result for each output
  126. row. But if we add an <code class="literal">ORDER BY</code> clause, we get very different
  127. results:
  128. </p><pre class="programlisting">
  129. SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
  130. </pre><pre class="screen">
  131. salary | sum
  132. --------+-------
  133. 3500 | 3500
  134. 3900 | 7400
  135. 4200 | 11600
  136. 4500 | 16100
  137. 4800 | 25700
  138. 4800 | 25700
  139. 5000 | 30700
  140. 5200 | 41100
  141. 5200 | 41100
  142. 6000 | 47100
  143. (10 rows)
  144. </pre><p>
  145. Here the sum is taken from the first (lowest) salary up through the
  146. current one, including any duplicates of the current one (notice the
  147. results for the duplicated salaries).
  148. </p><p>
  149. Window functions are permitted only in the <code class="literal">SELECT</code> list
  150. and the <code class="literal">ORDER BY</code> clause of the query. They are forbidden
  151. elsewhere, such as in <code class="literal">GROUP BY</code>, <code class="literal">HAVING</code>
  152. and <code class="literal">WHERE</code> clauses. This is because they logically
  153. execute after the processing of those clauses. Also, window functions
  154. execute after non-window aggregate functions. This means it is valid to
  155. include an aggregate function call in the arguments of a window function,
  156. but not vice versa.
  157. </p><p>
  158. If there is a need to filter or group rows after the window calculations
  159. are performed, you can use a sub-select. For example:
  160. </p><pre class="programlisting">
  161. SELECT depname, empno, salary, enroll_date
  162. FROM
  163. (SELECT depname, empno, salary, enroll_date,
  164. rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
  165. FROM empsalary
  166. ) AS ss
  167. WHERE pos &lt; 3;
  168. </pre><p>
  169. The above query only shows the rows from the inner query having
  170. <code class="literal">rank</code> less than 3.
  171. </p><p>
  172. When a query involves multiple window functions, it is possible to write
  173. out each one with a separate <code class="literal">OVER</code> clause, but this is
  174. duplicative and error-prone if the same windowing behavior is wanted
  175. for several functions. Instead, each windowing behavior can be named
  176. in a <code class="literal">WINDOW</code> clause and then referenced in <code class="literal">OVER</code>.
  177. For example:
  178. </p><pre class="programlisting">
  179. SELECT sum(salary) OVER w, avg(salary) OVER w
  180. FROM empsalary
  181. WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
  182. </pre><p>
  183. </p><p>
  184. More details about window functions can be found in
  185. <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>,
  186. <a class="xref" href="functions-window.html" title="9.21. Window Functions">Section 9.21</a>,
  187. <a class="xref" href="queries-table-expressions.html#QUERIES-WINDOW" title="7.2.5. Window Function Processing">Section 7.2.5</a>, and the
  188. <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> reference page.
  189. </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.4.5.6.9.5" class="footnote"><p><a href="#id-1.4.5.6.9.5" class="para"><sup class="para">[4] </sup></a>
  190. There are options to define the window frame in other ways, but
  191. this tutorial does not cover them. See
  192. <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a> for details.
  193. </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-transactions.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-inheritance.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.4. Transactions </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 3.6. Inheritance</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1