diff -urp views/handlers/views_handler_field.inc views/handlers/views_handler_field.inc
--- views/handlers/views_handler_field.inc	2009-06-03 15:55:52.000000000 -0400
+++ views/handlers/views_handler_field.inc	2009-09-01 12:20:15.109375000 -0400
@@ -48,6 +48,17 @@ class views_handler_field extends views_
     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 @@ class views_handler_field extends views_
    */
   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();
   }
 
@@ -181,6 +201,43 @@ class views_handler_field extends views_
       '#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.'),
+      );
+
+      $sql_functions = array(
+        'count' => t('Count'),
+        'sum' => t('Sum'),
+        'average' => t('Average'),
+        'minimum' => t('Minimum'),
+        'maximum' => t('Maximum'),
+        'concat' => t('Concatenate'),
+      );
+
+      $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;
diff -urp views/includes/query.inc views/includes/query.inc
--- views/includes/query.inc	2009-06-02 14:17:06.000000000 -0400
+++ views/includes/query.inc	2009-09-01 12:23:51.312500000 -0400
@@ -912,6 +912,9 @@ class views_query {
       }
     }
 
+    $has_groupby = FALSE;
+    $groupby_fields = array();
+
     $has_aggregate = FALSE;
     $non_aggregates = array();
 
@@ -928,6 +931,12 @@ class views_query {
       // 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[] = $fieldname;
+      }
+
       if (!empty($field['distinct'])) {
         $string = "DISTINCT($string)";
       }
@@ -935,6 +944,26 @@ class views_query {
         $string = "COUNT($string)";
         $has_aggregate = TRUE;
       }
+      else if (!empty($field['sum'])) {
+        $string = "SUM($string)";
+        $has_aggregate = TRUE;
+      }
+      else if (!empty($field['average'])) {
+        $string = "AVG($string)";
+        $has_aggregate = TRUE;
+      }
+      else if (!empty($field['minimum'])) {
+        $string = "MIN($string)";
+        $has_aggregate = TRUE;
+      }
+      else if (!empty($field['maximum'])) {
+        $string = "MAX($string)";
+        $has_aggregate = TRUE;
+      }
+      else if (!empty($field['concat'])) {
+        $string = "GROUP_CONCAT($string SEPARATOR ', ')";
+        $has_aggregate = TRUE;
+      }
       else if (!empty($field['aggregate'])) {
         $has_aggregate = TRUE;
       }
@@ -952,8 +981,8 @@ class views_query {
       }
     }
 
-    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');
       }
