Index: handlers/views_handler_field.inc
===================================================================
--- handlers/views_handler_field.inc	(Revision 9793)
+++ handlers/views_handler_field.inc	(Arbeitskopie)
 -48,6 +48,17 @@
     return TRUE;
   }
 
+  /**
+   * Determine if this field can be aggregated over.
+   *
+   * Fields can set this to FALSE if they do not wish to allow
+   * aggregation functions (such as COUNT, SUM, MAX, etc.) to be
+   * used on this field.
+   */
+  function allow_aggregation() {
+    return TRUE;
+  }
+
   function init(&$view, $options) {
     parent::init($view, $options);
 
 -61,9 +72,18 @@
    */
   function query() {
     $this->ensure_my_table();
-    // Add the field.
+
+    // Add the field, taking care of any aggregation that
+    // may affect it.
     $this->field_alias = $this->query->add_field($this->table_alias, $this->real_field);
 
+    if ($this->options['groupby']) {
+      $this->query->fields[$this->field_alias]['groupby'] = TRUE;
+    }
+    if ($this->options['aggregate']['aggregate_field']) {
+      $this->query->fields[$this->field_alias][$this->options['aggregate']['sql_function']] = TRUE;
+    }
+
     $this->add_additional_fields();
   }
 
 -185,7 +205,38 @@
       '#default_value' => $this->options['exclude'],
       '#description' => t('Check this box to not display this field, but still load it in the view.  Use this option to not show a grouping field in each record, or when doing advanced theming.'),
     );
+    $form['groupby'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Group this field'),
+      '#default_value' => $this->options['groupby'],
+      '#description' => t('Check this box if you want to group (summarize) this field and (optionally) aggregate another field.'),
+    );
 
+    if ($this->allow_aggregation()) {
+      $form['aggregate']['#tree'] = TRUE;
+      $form['aggregate']['aggregate_field'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Aggregate this field'),
+        '#default_value' => $this->options['aggregate']['aggregate_field'],
+        '#description' => t('Check this box if you want to apply an aggregation function (such as a count, average) to the values in this field.'),
+      );
+
+      views_include('query');
+      $sql_functions = views_query::get_aggregate_functions();
+
+      $form['aggregate']['sql_function'] = array(
+        '#type' => 'select',
+        '#title' => t('Aggregation function'),
+        '#default_value' => $this->options['aggregate']['sql_function'],
+        '#description' => t('The function that should be applied to the values in this field.'),
+        '#options' => $sql_functions,
+        '#process' => array('views_process_dependency'),
+        '#dependency' => array(
+          'edit-options-aggregate-aggregate-field' => array(1)
+        ),
+      );
+    }
+
     if ($this->allow_advanced_render()) {
       $form['alter']['#tree'] = TRUE;
       $form['alter']['alter_text'] = array(
Index: includes/query.inc
===================================================================
--- includes/query.inc	(Revision 9793)
+++ includes/query.inc	(Arbeitskopie)
 -936,6 +936,9 @@
       }
     }
 
+    $has_groupby = FALSE;
+    $groupby_fields = array();
+
     $has_aggregate = FALSE;
     $non_aggregates = array();
 
 -952,14 +955,26 @@
       // store for use with non-aggregates below
       $fieldname = (!empty($field['alias']) ? $field['alias'] : $string);
 
+      // check for and store group by fields
+      if(!empty($field['groupby'])) {
+        $has_groupby = TRUE;
+        $groupby_fields[] = $string;
+      }
+
       if (!empty($field['distinct'])) {
         $string = "DISTINCT($string)";
       }
-      if (!empty($field['count'])) {
-        $string = "COUNT($string)";
-        $has_aggregate = TRUE;
+
+      $aggregate_functions = $this->get_aggregate_functions($string);
+      foreach ($aggregate_functions as $key => $aggregate_function) {
+        if (!empty($field[$key])) {
+          $string = $aggregate_function;
+          $has_aggregate = TRUE;
+          break;
+        }
       }
-      else if (!empty($field['aggregate'])) {
+
+      if (!$has_aggregate && !empty($field['aggregate'])) {
         $has_aggregate = TRUE;
       }
       elseif ($this->distinct && !in_array($fieldname, $this->groupby)) {
 -979,8 +995,8 @@
       }
     }
 
-    if ($has_aggregate || $this->groupby) {
-      $groupby = "GROUP BY " . implode(', ', array_unique(array_merge($this->groupby, $non_aggregates))) . "\n";
+    if ($has_aggregate || $has_groupby || $this->groupby) {
+      $groupby = "GROUP BY " . implode(', ', array_unique($has_groupby ? $groupby_fields : array_merge($this->groupby, $non_aggregates))) . "\n";
       if ($this->having) {
         $having = $this->condition_sql('having');
       }
 -1016,5 +1032,30 @@
     }
     return $args;
   }
+
+  /**
+   * Get the available aggregate functions for the current DB
+   * backend.
+   */
+  static function get_aggregate_functions($string = FALSE) {
+    $functions = array();
+    // Add ANSI functions
+    if (!$string) {
+      $functions['average'] = t('Average');
+      $functions['sum'] = t('Sum');
+      $functions['count'] = t('Count');
+      $functions['minimum'] = t('Minimum');
+      $functions['maximum'] = t('Maximum');
+    }
+    else {
+      $functions['average'] = "AVG($string)";
+      $functions['sum'] = "SUM($string)";
+      $functions['count'] = "COUNT($string)";
+      $functions['minimum'] = "MIN($string)";
+      $functions['maximum'] = "MAX($string)";
+    }
+
+    return $functions;
+  }
 }
