diff --git a/handlers/views_handler_filter.inc b/handlers/views_handler_filter.inc
index 541e5df..3109d37 100644
--- a/handlers/views_handler_filter.inc
+++ b/handlers/views_handler_filter.inc
@@ -582,6 +582,21 @@ class views_handler_filter extends views_handler {
   }
 
   /**
+   * Beside ensure the table, this function takes care about setting the group options right.
+   */
+  function ensure_my_table() {
+    // 0 is a special group, so take sure that all filter groups have a higher
+    // number then 0, so find the smallest.
+    $filters_groups = $this->view->display_handler->options['filter_groups']['groups'];
+    $lowest = min(array_keys($filters_groups));
+    $offset = $lowest + 1;
+    $this->options['group'] += $offset;
+
+    return parent::ensure_my_table();
+  }
+
+
+  /**
    * Add this filter to the query.
    *
    * Due to the nature of fapi, the value and the operator have an unintended
@@ -590,6 +605,7 @@ class views_handler_filter extends views_handler {
    */
   function query() {
     $this->ensure_my_table();
+    dsm($this->options['group']);
     $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator);
   }
 
diff --git a/includes/view.inc b/includes/view.inc
index 602e90e..6f29962 100644
--- a/includes/view.inc
+++ b/includes/view.inc
@@ -839,10 +839,22 @@ class view extends views_db_object {
 
     // Set the filtering groups.
     if (!empty($this->filter)) {
+      // Setup the special group 0, which has always AND.
+      $this->query->set_group_operator('AND');
+      $this->query->set_where_group('AND', 0);
+
       $filter_groups = $this->display_handler->get_option('filter_groups');
+
+      // 0 is a special group, so take sure that all filter groups have a higher
+      // number then 0, so find the smallest.
+      $filters_groups = $this->view->display_handler->options['filter_groups']['groups'];
+      $lowest = min(array_keys($filters_groups));
+      $offset = $lowest + 1;
+
       if ($filter_groups) {
         $this->query->set_group_operator($filter_groups['operator']);
         foreach($filter_groups['groups'] as $id => $operator) {
+          $id += $offset;
           $this->query->set_where_group($operator, $id);
         }
       }
diff --git a/plugins/views_plugin_query_default.inc b/plugins/views_plugin_query_default.inc
index 082ff33..93ae081 100644
--- a/plugins/views_plugin_query_default.inc
+++ b/plugins/views_plugin_query_default.inc
@@ -793,11 +793,12 @@ class views_plugin_query_default extends views_plugin_query {
   function add_where($group, $field, $value = NULL, $operator = NULL) {
     // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
     // the default group.
+    // The 0 group is defined to be always AND.
     if (empty($group)) {
       $group = 0;
     }
 
-    // Check for a group.
+    // Check for a group
     if (!isset($this->where[$group])) {
       $this->set_where_group('AND', $group);
     }
@@ -1037,24 +1038,8 @@ class views_plugin_query_default extends views_plugin_query {
     $has_condition = FALSE;
     $main_group = $this->group_operator == 'OR' ? db_or() : db_and();
     foreach ($this->$where as $group => $info) {
-      if (!empty($info['conditions'])) {
-        $sub_group = $info['type'] == 'OR' ? db_or() : db_and();
-        foreach ($info['conditions'] as $key => $clause) {
-          // DBTNG doesn't support to add the same subquery twice to the main
-          // query and the count query, so clone the subquery to have two instances
-          // of the same object. - http://drupal.org/node/1112854
-          if (is_object($clause['value']) && $clause['value'] instanceof SelectQuery) {
-            $clause['value'] = clone $clause['value'];
-          }
-          if ($clause['operator'] == 'formula') {
-            $has_condition = TRUE;
-            $sub_group->where($clause['field'], $clause['value']);
-          }
-          else {
-            $has_condition = TRUE;
-            $sub_group->condition($clause['field'], $clause['value'], $clause['operator']);
-          }
-        }
+      if ($sub_group = $this->build_condition_group($info)) {
+        $has_condition = TRUE;
         $main_group->condition($sub_group);
       }
     }
@@ -1064,6 +1049,46 @@ class views_plugin_query_default extends views_plugin_query {
   }
 
   /**
+   * Constructs a single "WHERE" or "HAVING" group.
+   *
+   * @param $info
+   *   Info describes the elements of a condition group, containing possible sub-conditions or condition groups.
+   *
+   * @return DatabaseCondition
+   *   Returns a database condition containing an AND or
+   */
+  function build_condition_group($info) {
+    if (!empty($info['conditions'])) {
+      $sub_group = $info['type'] == 'OR' ? db_or() : db_and();
+      foreach ($info['conditions'] as $key => $clause) {
+        // DBTNG doesn't support to add the same subquery twice to the main
+        // query and the count query, so clone the subquery to have two instances
+        // of the same object. - http://drupal.org/node/1112854
+        if (is_object($clause['value']) && $clause['value'] instanceof SelectQuery) {
+          $clause['value'] = clone $clause['value'];
+        }
+        if ($clause['operator'] == 'formula') {
+          $has_condition = TRUE;
+          $sub_group->where($clause['field'], $clause['value']);
+        }
+        // Make a recursive call so any level of groups are supported.
+        elseif ($clause['group']) {
+          if ($subsub_group = $this->build_condition_group($clause['group'])) {
+            $sub_group->condition($subsub_group);
+          }
+        }
+        else {
+          $has_condition = TRUE;
+          $sub_group->condition($clause['field'], $clause['value'], $clause['operator']);
+        }
+      }
+      if ($has_condition) {
+        return $sub_group;
+      }
+    }
+  }
+
+  /**
    * Build fields array.
    */
   function compile_fields($fields_array, $query) {
