diff --git a/var/Typecho/Db/Adapter/Mysql.php b/var/Typecho/Db/Adapter/Mysql.php
index a842b97f..0cd7781d 100644
--- a/var/Typecho/Db/Adapter/Mysql.php
+++ b/var/Typecho/Db/Adapter/Mysql.php
@@ -146,7 +146,7 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 
     /**
diff --git a/var/Typecho/Db/Adapter/Pdo/Mysql.php b/var/Typecho/Db/Adapter/Pdo/Mysql.php
index d2528956..a6bfebb7 100644
--- a/var/Typecho/Db/Adapter/Pdo/Mysql.php
+++ b/var/Typecho/Db/Adapter/Pdo/Mysql.php
@@ -87,6 +87,6 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 }
diff --git a/var/Typecho/Db/Adapter/Pdo/Pgsql.php b/var/Typecho/Db/Adapter/Pdo/Pgsql.php
index 48e4e258..f6951c40 100644
--- a/var/Typecho/Db/Adapter/Pdo/Pgsql.php
+++ b/var/Typecho/Db/Adapter/Pdo/Pgsql.php
@@ -74,7 +74,7 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 
     /**
diff --git a/var/Typecho/Db/Adapter/Pdo/SQLite.php b/var/Typecho/Db/Adapter/Pdo/SQLite.php
index a7b3584c..6160a0c3 100644
--- a/var/Typecho/Db/Adapter/Pdo/SQLite.php
+++ b/var/Typecho/Db/Adapter/Pdo/SQLite.php
@@ -73,6 +73,6 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 }
diff --git a/var/Typecho/Db/Adapter/Pgsql.php b/var/Typecho/Db/Adapter/Pgsql.php
index 750fc6f9..cae967e4 100644
--- a/var/Typecho/Db/Adapter/Pgsql.php
+++ b/var/Typecho/Db/Adapter/Pgsql.php
@@ -154,7 +154,7 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 
     /**
diff --git a/var/Typecho/Db/Adapter/SQLite.php b/var/Typecho/Db/Adapter/SQLite.php
index 9142c1d8..12cff823 100644
--- a/var/Typecho/Db/Adapter/SQLite.php
+++ b/var/Typecho/Db/Adapter/SQLite.php
@@ -174,7 +174,7 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter
         $sql['offset'] = (0 == strlen($sql['offset'])) ? NULL : ' OFFSET ' . $sql['offset'];
 
         return 'SELECT ' . $sql['fields'] . ' FROM ' . $sql['table'] .
-        $sql['where'] . $sql['group'] . $sql['order'] . $sql['limit'] . $sql['offset'];
+        $sql['where'] . $sql['group'] . $sql['having'] . $sql['order'] . $sql['limit'] . $sql['offset'];
     }
 
     /**
diff --git a/var/Typecho/Db/Query.php b/var/Typecho/Db/Query.php
index 76dc2e86..65cac471 100644
--- a/var/Typecho/Db/Query.php
+++ b/var/Typecho/Db/Query.php
@@ -73,6 +73,7 @@ class Typecho_Db_Query
             'offset' => NULL,
             'order'  => NULL,
             'group'  => NULL,
+            'having'  => NULL,
             'rows'   => array(),
         );
     }
@@ -339,6 +340,28 @@ class Typecho_Db_Query
         return $this;
     }
 
+    /**
+     * HAVING (HAVING)
+     *
+     * @return Typecho_Db_Query
+     */
+    public function having()
+    {
+        $condition = func_get_arg(0);
+        $condition = str_replace('?', "%s", $this->filterColumn($condition));
+        $operator = empty($this->_sqlPreBuild['having']) ? ' HAVING ' : ' AND';
+
+        if (func_num_args() <= 1) {
+            $this->_sqlPreBuild['having'] .= $operator . ' (' . $condition . ')';
+        } else {
+            $args = func_get_args();
+            array_shift($args);
+            $this->_sqlPreBuild['having'] .= $operator . ' (' . vsprintf($condition, array_map(array($this->_adapter, 'quoteValue'), $args)) . ')';
+        }
+
+        return $this;
+    }
+
     /**
      * 选择查询字段
      *