diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php
index e73925220f2aa18943ee3c5d070520a803b4796a..8a2f60d1810f5d283ec3d8667e80904479d1033c 100644
--- a/CRM/Report/Form.php
+++ b/CRM/Report/Form.php
@@ -2129,12 +2129,30 @@ class CRM_Report_Form extends CRM_Core_Form {
    * @return string
    */
   public function whereSubtypeClause($field, $value, $op) {
+    // Get the correct SQL operator.
+    switch ($op) {
+      case 'notin':
+        $op = 'nhas';
+        $clauseSeparator = 'AND';
+        break;
+
+      case 'in':
+        $op = 'has';
+        $clauseSeparator = 'OR';
+        break;
+    }
+    $sqlOp = $this->getSQLOperator($op);
     $clause = '( ';
     $subtypeFilters = count($value);
-    for ($i = 0; $i < $subtypeFilters; $i++) {
-      $clause .= "{$field['dbAlias']} LIKE '%$value[$i]%'";
-      if ($i !== ($subtypeFilters - 1)) {
-        $clause .= " OR ";
+    if ($sqlOp == 'IS NULL' || $sqlOp == 'IS NOT NULL') {
+      $clause .= "{$field['dbAlias']} $sqlOp";
+    }
+    else {
+      for ($i = 0; $i < $subtypeFilters; $i++) {
+        $clause .= "{$field['dbAlias']} $sqlOp '%$value[$i]%'";
+        if ($i !== ($subtypeFilters - 1)) {
+          $clause .= " $clauseSeparator ";
+        }
       }
     }
     $clause .= ' )';
diff --git a/tests/phpunit/api/v3/ReportTemplateTest.php b/tests/phpunit/api/v3/ReportTemplateTest.php
index beae3d5b16cae23bc4960bf6a419ef70b0ac0aef..1c110734fad1591ba10e1bf2c9634055586331ee 100644
--- a/tests/phpunit/api/v3/ReportTemplateTest.php
+++ b/tests/phpunit/api/v3/ReportTemplateTest.php
@@ -1123,6 +1123,44 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
     $this->assertEquals(1, $rows['count']);
   }
 
+  /**
+   * Test contact subtype filter on summary report.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testContactSubtypeNotNull() {
+    $this->individualCreate(['contact_sub_type' => ['Student', 'Parent']]);
+    $this->individualCreate();
+
+    $rows = $this->callAPISuccess('report_template', 'getrows', [
+      'report_id' => 'contact/summary',
+      'contact_sub_type_op' => 'nnll',
+      'contact_sub_type_value' => [],
+      'contact_type_op' => 'eq',
+      'contact_type_value' => 'Individual',
+    ]);
+    $this->assertEquals(1, $rows['count']);
+  }
+
+  /**
+   * Test contact subtype filter on summary report.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testContactSubtypeNull() {
+    $this->individualCreate(['contact_sub_type' => ['Student', 'Parent']]);
+    $this->individualCreate();
+
+    $rows = $this->callAPISuccess('report_template', 'getrows', [
+      'report_id' => 'contact/summary',
+      'contact_sub_type_op' => 'nll',
+      'contact_sub_type_value' => [],
+      'contact_type_op' => 'eq',
+      'contact_type_value' => 'Individual',
+    ]);
+    $this->assertEquals(1, $rows['count']);
+  }
+
   /**
    * Test PCP report to ensure total donors and total committed is accurate.
    */