xaggr.sgml
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:3k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. <Chapter Id="xaggr">
  2. <Title>Extending <Acronym>SQL</Acronym>: Aggregates</Title>
  3. <Para>
  4.      Aggregates  in <ProductName>Postgres</ProductName> 
  5. are expressed in terms of state
  6.      transition functions.  That is,  an  aggregate  can  be
  7.      defined  in terms of state that is modified whenever an
  8.      instance is processed.  Some state functions look at  a
  9.      particular value in the instance when computing the new
  10.      state (<Acronym>sfunc1</Acronym> in the  
  11. create  aggregate  syntax)  while
  12.      others  only  keep  track  of  their own internal state
  13.      (<Acronym>sfunc2</Acronym>).
  14.      If we define an aggregate that  uses  only  
  15. <Acronym>sfunc1</Acronym>,  we
  16.      define an aggregate that computes a running function of
  17.      the attribute values from each instance.  "Sum"  is  an
  18.      example  of  this  kind  of aggregate.  "Sum" starts at
  19.      zero and always adds the current  instance's  value  to
  20.      its  running  total.   We  will  use the 
  21. <Acronym>int4pl</Acronym> that is
  22.      built into <ProductName>Postgres</ProductName> 
  23. to perform this addition.
  24.      
  25. <ProgramListing>
  26. CREATE AGGREGATE complex_sum (
  27.     sfunc1 = complex_add,
  28.     basetype = complex,
  29.     stype1 = complex,
  30.     initcond1 = '(0,0)'
  31. );
  32. SELECT complex_sum(a) FROM test_complex;
  33.          +------------+
  34.          |complex_sum |
  35.          +------------+
  36.          |(34,53.9)   |
  37.          +------------+
  38. </ProgramListing>
  39. </Para>
  40. <Para>
  41.      If we define only <Acronym>sfunc2</Acronym>, we are 
  42. specifying  an  aggregate  
  43.      that computes a running function that is independent  of  
  44.      the  attribute  values  from  each  instance.
  45.      "Count"  is  the  most  common  example of this kind of
  46.      aggregate.  "Count" starts at zero and adds one to  its
  47.      running  total for each instance, ignoring the instance
  48.      value.  Here, we use the built-in 
  49. <Acronym>int4inc</Acronym> routine to do
  50.      the work for us.  This routine increments (adds one to)
  51.      its argument.
  52.      
  53. <ProgramListing>
  54. CREATE AGGREGATE my_count (
  55.     sfunc2 = int4inc, -- add one
  56.     basetype = int4,
  57.     stype2 = int4,
  58.     initcond2 = '0'
  59. );
  60. SELECT my_count(*) as emp_count from EMP;
  61.          +----------+
  62.          |emp_count |
  63.          +----------+
  64.          |5         |
  65.          +----------+
  66. </ProgramListing>
  67. </Para>
  68.          
  69. <Para>
  70.      "Average" is an example of an aggregate  that  requires
  71.      both  a function to compute the running sum and a function 
  72.      to compute the running count.   When  all  of  the
  73.      instances have been processed, the final answer for the
  74.      aggregate is the running sum  divided  by  the  running
  75.      count.   We use the <Acronym>int4pl</Acronym> and <Acronym>int4inc</Acronym> routines we used
  76.      before as well as the <ProductName>Postgres</ProductName>  integer  division  
  77.      routine,  <Acronym>int4div</Acronym>,  to  compute the division of the sum by
  78.      the count.
  79.      
  80. <ProgramListing>
  81. CREATE AGGREGATE my_average (
  82.     sfunc1 = int4pl,     --  sum
  83.     basetype = int4,
  84.     stype1 = int4,
  85.     sfunc2 = int4inc,    -- count
  86.     stype2 = int4,
  87.     finalfunc = int4div, -- division
  88.     initcond1 = '0',
  89.     initcond2 = '0'
  90. );
  91. SELECT my_average(salary) as emp_average FROM EMP;
  92.          +------------+
  93.          |emp_average |
  94.          +------------+
  95.          |1640        |
  96.          +------------+
  97. </ProgramListing>
  98. </Para>
  99. </Chapter>