diff --git a/include/class.forms.php b/include/class.forms.php
index 50b2e6db5747601afb94b4ae446f89046b4aef6e..f085a6746842c4ceea22966851b1a69453315199 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1043,6 +1043,13 @@ class FormField {
 
     function getLabel() { return $this->get('label'); }
 
+    function applyOrderBy($query, $reverse=false, $name=false) {
+        $col = $name ?: CustomQueue::getOrmPath($this->get('name'), $query);
+        if ($reverse)
+            $col = '-' . $col;
+        return $query->order_by($col);
+    }
+
     /**
      * getImpl
      *
@@ -2361,6 +2368,20 @@ class PriorityField extends ChoiceField {
             $config['default'] = $cfg->getDefaultPriorityId();
         return $config;
     }
+
+    function applyOrderBy($query, $reverse=false, $name=false) {
+        if ($query->model == 'Ticket' && $name == 'cdata__priority') {
+            // Order by the priority urgency field
+            $col = 'cdata__:priority__priority_urgency';
+            $reverse = !$reverse;
+        }
+        else {
+            $col = $name ?: CustomQueue::getOrmPath($this->get('name'), $query);
+        }
+        if ($reverse)
+            $col = "-$col";
+        return $query->order_by($col);
+    }
 }
 FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
     return array(
diff --git a/include/class.queue.php b/include/class.queue.php
index a0e7c57ec6a0038cec9e5dafaf671af01e06cc15..4f782f0974bbddbdfee5496a9e93742002d65b99 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -270,14 +270,14 @@ class CustomQueue extends VerySimpleModel {
     ) {
         static $cache = array(), $otherFields;
 
-        if (!in_array('Searchable', class_implements($base)))
-            return array();
-
         // Early exit if already cached
         $fields = &$cache[$base];
         if ($fields)
             return $fields;
 
+        if (!in_array('Searchable', class_implements($base)))
+            return array();
+
         $fields = $fields ?: array();
         foreach ($base::getSearchableFields() as $path=>$F) {
             if (is_array($F)) {
@@ -1534,6 +1534,21 @@ extends VerySimpleModel {
         return $query;
     }
 
+    function applySort($query, $reverse=false) {
+        $fields = CustomQueue::getSearchableFields($root ?: $this->getQueue()->getRoot());
+        if ($primary = $fields[$this->primary]) {
+            list(,$field) = $primary;
+            $query = $field->applyOrderBy($query, $reverse,
+                CustomQueue::getOrmPath($this->primary, $query));
+        }
+        if ($secondary = $fields[$this->secondary]) {
+            list(,$field) = $secondary;
+            $query = $field->applyOrderBy($query, $reverse,
+                CustomQueue::getOrmPath($this->secondary, $query));
+        }
+        return $query;
+    }
+
     function getDataConfigForm($source=false) {
         return new QueueColDataConfigForm($source ?: $this->getDbFields(),
             array('id' => $this->id));
diff --git a/include/class.search.php b/include/class.search.php
index 66eae2ba56a335a03749a9015c9a2a416cae3bae..efbbdd3a90b093a32418d9ce9f604032313610b4 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -824,18 +824,48 @@ class AssigneeChoiceField extends ChoiceField {
     function display($value) {
         return (string) $value;
     }
+
+    function applyOrderBy($query, $reverse=false, $name=false) {
+        $reverse = $reverse ? '-' : '';
+        return $query->order_by("{$reverse}staff__firstname",
+            "{$reverse}staff__lastname", "{$reverse}team__name");
+    }
 }
 
 class AgentSelectionField extends ChoiceField {
     function getChoices() {
         return Staff::getStaffMembers();
     }
+
+    function applyOrderBy($query, $reverse=false, $name=false) {
+        global $cfg;
+
+        $reverse = $reverse ? '-' : '';
+        switch ($cfg->getAgentNameFormat()) {
+        case 'last':
+        case 'lastfirst':
+        case 'legal':
+            $query->order_by("{$reverse}staff__lastname",
+                "{$reverse}staff__firstname");
+            break;
+
+        default:
+            $query->order_by("{$reverse}staff__firstname",
+                "{$reverse}staff__lastname");
+        }
+        return $query;
+    }
 }
 
 class TeamSelectionField extends ChoiceField {
     function getChoices() {
         return Team::getTeams();
     }
+
+    function applyOrderBy($query, $reverse=false, $name=false) {
+        $reverse = $reverse ? '-' : '';
+        return $query->order_by("{$reverse}team__name");
+    }
 }
 
 class TicketStateChoiceField extends ChoiceField {
diff --git a/include/staff/templates/queue-tickets.tmpl.php b/include/staff/templates/queue-tickets.tmpl.php
index 7725d04deea4a9c37a2de5e22d775ef644b8ce44..0cf3ad09d44bc37a171d67a6bf2f206abc5a0546 100644
--- a/include/staff/templates/queue-tickets.tmpl.php
+++ b/include/staff/templates/queue-tickets.tmpl.php
@@ -192,10 +192,7 @@ foreach ($columns as $C) {
 
     // Sort by this column ?
     if (isset($sort['col']) && $sort['col'] == $C->id) {
-        $col = CustomQueue::getOrmPath($C->primary, $query);
-        if ($sort['dir'])
-            $col = '-' . $col;
-        $tickets = $tickets->order_by($col);
+        $tickets = $C->applySort($tickets, $sort['dir']);
     }
 } ?>
     </tr>