diff --git a/classes/form/form_delays_filter.php b/classes/form/form_delays_filter.php
new file mode 100644
index 0000000000000000000000000000000000000000..662cb5ae821cf899400f54a236b4dd28a3a2c7b3
--- /dev/null
+++ b/classes/form/form_delays_filter.php
@@ -0,0 +1,98 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * A moodle form for filtering the coursedelays table
+ *
+ * @package    tool_lifecycle
+ * @copyright  2019 Justus Dieckmann WWU
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_lifecycle\form;
+
+use tool_lifecycle\action;
+use tool_lifecycle\entity\step_subplugin;
+use tool_lifecycle\entity\workflow;
+use tool_lifecycle\manager\lib_manager;
+use tool_lifecycle\manager\workflow_manager;
+use tool_lifecycle\step\libbase;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir . '/formslib.php');
+
+/**
+ * A moodle form for filtering the coursedelays table
+ *
+ * @package    tool_lifecycle
+ * @copyright  2019 Justus Dieckmann WWU
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class form_delays_filter extends \moodleform {
+
+    /**
+     * Constructor
+     *
+     * @param \moodle_url $url .
+     */
+    public function __construct($url) {
+        parent::__construct($url);
+    }
+
+    /**
+     * Defines forms elements
+     */
+    public function definition() {
+        $mform = $this->_form;
+
+        $activeworkflows = workflow_manager::get_active_workflows();
+        $workflowoptions = [
+                '' => get_string('all_delays', 'tool_lifecycle'),
+                'global' => get_string('globally', 'tool_lifecycle')
+        ];
+        foreach ($activeworkflows as $activeworkflow) {
+            $workflowoptions[$activeworkflow->id] = get_string('delays_for_workflow', 'tool_lifecycle',
+                    $activeworkflow->displaytitle);
+        }
+        $mform->addElement('select', 'workflow', get_string('show_delays', 'tool_lifecycle'), $workflowoptions);
+
+        $categories = \core_course_category::get_all();
+        $categoryoptions = ['' => '-'];
+        foreach ($categories as $category) {
+            $categoryoptions[$category->id] = $category->name;
+        }
+        $mform->addElement('select', 'category', get_string('category'), $categoryoptions);
+
+        $mform->addElement('text', 'coursename', get_string('course'));
+        $mform->setType('coursename', PARAM_TEXT);
+
+        $this->add_action_buttons(true, get_string('apply', 'tool_lifecycle'));
+    }
+
+    public function definition_after_data() {
+        $cache = \cache::make('tool_lifecycle', 'mformdata');
+        if ($this->is_submitted() && $this->is_validated()) {
+            if ($this->is_cancelled()) {
+                $cache->delete('delays_filter');
+            } else {
+                $cache->set('delays_filter', $this->get_data());
+            }
+        } else {
+            $this->set_data($cache->get('delays_filter'));
+        }
+    }
+
+}
diff --git a/classes/table/delayed_courses_table.php b/classes/table/delayed_courses_table.php
index e3f4d653c5f58bbd3a9170680177612bb8045c46..d6558834897dfec92b1e74621e0ff02cb75d06cc 100644
--- a/classes/table/delayed_courses_table.php
+++ b/classes/table/delayed_courses_table.php
@@ -36,30 +36,82 @@ require_once($CFG->libdir . '/tablelib.php');
  */
 class delayed_courses_table extends \table_sql {
 
-    /**
-     * Constructor for deactivated_workflows_table.
+    /** @var $filterdata object|null data from mform */
+    private $filterdata;
 
+    /**
+     * Constructor for delayed_courses_table.
      */
-    public function __construct() {
+    public function __construct($filterdata) {
         parent::__construct('tool_lifecycle-delayed-courses');
-        $fields = 'c.id as courseid, c.fullname as coursefullname, cat.name as category, dw.workflowid, w.title as workflow, dw.delayeduntil AS workflowdelay, d.delayeduntil AS globaldelay, maxtable.wfcount AS workflowcount';
-
-        $from = '(' .
-                'SELECT courseid, MAX(dw.id) AS maxid, COUNT(*) AS wfcount ' .
-                'FROM {tool_lifecycle_delayed_workf} dw ' .
-                'JOIN {tool_lifecycle_workflow} w ON dw.workflowid = w.id ' . // To make sure no outdated delays are counted.
-                'WHERE dw.delayeduntil >= :time ' .
-                'AND w.timeactive IS NOT NULL ' .
-                // TODO AND dw.workflowid IN $workflows
-                'GROUP BY courseid ' .
-            ') maxtable ' .
-            'JOIN {tool_lifecycle_delayed_workf} dw ON maxtable.maxid = dw.id ' .
-            'JOIN {tool_lifecycle_workflow} w ON dw.workflowid = w.id ' .
-            'FULL JOIN  {tool_lifecycle_delayed} d ON dw.courseid = d.courseid ' .
-            'JOIN {course} c ON c.id = COALESCE(dw.courseid, d.courseid) ' .
-            'JOIN {course_categories} cat ON c.category = cat.id';
+        $this->filterdata = $filterdata;
+
+        $fields = 'c.id as courseid, c.fullname as coursefullname, cat.name as category, ';
+
+        $selectseperatedelays = true;
+        $selectglobaldelays = true;
+        $workflowfilterid = null;
+        if ($filterdata && $filterdata->workflow) {
+            if ($filterdata->workflow == 'global') {
+                $selectseperatedelays = false;
+            } else if (is_number($filterdata->workflow)) {
+                $selectglobaldelays = false;
+                $workflowfilterid = $filterdata->workflow;
+            } else {
+                throw new \coding_exception('action has to be "global" or a int value');
+            }
+        }
+
+
+
+        if ($selectseperatedelays) {
+            $fields .= 'dw.workflowid, w.title as workflow, dw.delayeduntil AS workflowdelay, maxtable.wfcount AS workflowcount, ';
+        } else {
+            $fields .= 'null as workflowid, null as workflow, null AS workflowdelay, null AS workflowcount, ';
+        }
+
+        $params = [];
+
+        if ($selectglobaldelays) {
+            $fields .= 'd.delayeduntil AS globaldelay';
+        } else {
+            $fields .= 'null AS globaldelay';
+        }
+
+        if ($selectglobaldelays && !$selectseperatedelays) {
+            $from = '{tool_lifecycle_delayed} d ' .
+                    'JOIN {course} c ON c.id = d.courseid ' .
+                    'JOIN {course_categories} cat ON c.category = cat.id';
+        } else {
+            $from = '(' .
+                    'SELECT courseid, MAX(dw.id) AS maxid, COUNT(*) AS wfcount ' .
+                    'FROM {tool_lifecycle_delayed_workf} dw ' .
+                    'JOIN {tool_lifecycle_workflow} w ON dw.workflowid = w.id ' . // To make sure no outdated delays are counted.
+                    'WHERE dw.delayeduntil >= :time ' .
+                    'AND w.timeactive IS NOT NULL ';
+            $params['time'] = time();
+
+            if ($workflowfilterid) {
+                $from .= 'AND w.id = :workflowid';
+                $params['workflowid'] = $workflowfilterid;
+            }
+
+            $from .= 'GROUP BY courseid ' .
+                    ') maxtable ' .
+                    'JOIN {tool_lifecycle_delayed_workf} dw ON maxtable.maxid = dw.id ' .
+                    'JOIN {tool_lifecycle_workflow} w ON dw.workflowid = w.id ';
+
+            if ($selectglobaldelays) {
+                $from .= 'FULL JOIN {tool_lifecycle_delayed} d ON dw.courseid = d.courseid ' .
+                        'JOIN {course} c ON c.id = COALESCE(dw.courseid, d.courseid) ';
+            } else {
+                $from .= 'JOIN {course} c ON c.id = dw.courseid ';
+            }
+
+            $from .= 'JOIN {course_categories} cat ON c.category = cat.id';
+        }
+
         $where = 'true';
-        $params = ['time' => time()];
 
         $this->set_sql($fields, $from, $where, $params);
         $this->column_nosort = ['workflow', 'tools'];
@@ -72,6 +124,14 @@ class delayed_courses_table extends \table_sql {
         ]);
     }
 
+    /**
+     * Render workflow column
+     *
+     * @param $row
+     * @return string
+     * @throws \coding_exception
+     * @throws \dml_exception
+     */
     public function col_workflow($row) {
         if($row->globaldelay >= time()) {
             if ($row->workflowcount == 1) {
@@ -101,6 +161,14 @@ class delayed_courses_table extends \table_sql {
                 \html_writer::end_span();
     }
 
+    /**
+     * Returns mouseover text for Delaystatus.
+     *
+     * @param $row
+     * @return string
+     * @throws \coding_exception
+     * @throws \dml_exception
+     */
     private function get_mouseover($row) {
         global $DB;
         $text = '';
@@ -114,10 +182,14 @@ class delayed_courses_table extends \table_sql {
             $text .= get_string('name_until_date', 'tool_lifecycle',
                     array('name' => $row->workflow, 'date' => $date)) . '&#13;';
         } else if ($row->workflowcount > 1) {
+
+            // TODO Make sure dw.workflowid is distinct.
+
             $sql = 'SELECT dw.id, dw.delayeduntil, w.title
                     FROM {tool_lifecycle_delayed_workf} dw
                     JOIN {tool_lifecycle_workflow} w ON dw.workflowid = w.id
-                    WHERE dw.courseid = :courseid';
+                    WHERE dw.courseid = :courseid
+                    AND w.timeactive IS NOT NULL';
             $records = $DB->get_records_sql($sql, ['courseid' => $row->courseid]);
             foreach ($records as $record) {
                 $date = userdate($record->delayeduntil, $dateformat);
@@ -137,9 +209,14 @@ class delayed_courses_table extends \table_sql {
      */
     public function col_tools($row) {
         global $PAGE, $OUTPUT;
+        // TODO Add view specific workflow parameter.
+
         $button = new \single_button(
-                new \moodle_url($PAGE->url,
-                        array('action' => 'delete', 'cid' => $row->courseid, 'sesskey' => sesskey())),
+                new \moodle_url($PAGE->url, array(
+                        'action' => 'delete',
+                        'cid' => $row->courseid,
+                        'sesskey' => sesskey()
+                )),
                 get_string('delete_delay', 'tool_lifecycle'));
         return $OUTPUT->render($button);
     }
diff --git a/db/caches.php b/db/caches.php
new file mode 100644
index 0000000000000000000000000000000000000000..209ad71674069f7ad5d7dccf6d6c1d3d8d4c7952
--- /dev/null
+++ b/db/caches.php
@@ -0,0 +1,32 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Cache Definition for Admin Approve Step
+ *
+ * @package tool_lifecycle_step
+ * @subpackage adminapprove
+ * @copyright  2019 Justus Dieckmann WWU
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$definitions = array(
+        'mformdata' => array(
+                'mode' => cache_store::MODE_SESSION
+        )
+);
\ No newline at end of file
diff --git a/delayedcourses.php b/delayedcourses.php
index 33fabc725bce74e5c8d68de3cf85e855af62bed5..c648443ac8c806084b3520d715f75cceab845acb 100644
--- a/delayedcourses.php
+++ b/delayedcourses.php
@@ -22,6 +22,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+use tool_lifecycle\form\form_delays_filter;
 use tool_lifecycle\table\delayed_courses_table;
 
 require_once(__DIR__ . '/../../../config.php');
@@ -59,9 +60,14 @@ $PAGE->set_url(new \moodle_url('/admin/tool/lifecycle/delayedcourses.php'));
 $PAGE->set_title(get_string('delayed_courses_header', 'tool_lifecycle'));
 $PAGE->set_heading(get_string('delayed_courses_header', 'tool_lifecycle'));
 
-$table = new delayed_courses_table();
+$mform = new form_delays_filter($PAGE->url);
+
+$data = $mform->get_data();
+
+$table = new delayed_courses_table($data);
 $table->define_baseurl($PAGE->url);
 
 echo $OUTPUT->header();
+$mform->display();
 $table->out(100, false);
 echo $OUTPUT->footer();
diff --git a/lang/en/tool_lifecycle.php b/lang/en/tool_lifecycle.php
index b7e5e5c6342921e7691058236d0811869a9219f4..a92b9c7804929d7819bc661116ca5157c5f18975 100644
--- a/lang/en/tool_lifecycle.php
+++ b/lang/en/tool_lifecycle.php
@@ -199,5 +199,9 @@ $string['delayed_globally_and_seperately_for_one'] = 'Delayed globally and seper
 $string['delayed_globally'] = 'Delayed globally until {$a}';
 $string['delayed_for_workflow_until'] = 'Delayed for "{$a->name}" until {$a->date}';
 $string['delayed_for_workflows'] = 'Delayed for {$a} workflows';
-$string['delays'] = "Delays";
-
+$string['delays'] = 'Delays';
+$string['apply'] = 'Apply';
+$string['show_delays'] = 'Kind of view';
+$string['all_delays'] = 'All delays';
+$string['globally'] = 'Global delays';
+$string['delays_for_workflow'] = 'Delays for "{$a}"';