diff --git a/includes/database/pgsql/query.inc b/includes/database/pgsql/query.inc
index 9005a1a83718e943d1a2e7a198c95fdf95b40f7b..ac5072c76f7152658180cabe7cc5c7081351a321 100644
--- a/includes/database/pgsql/query.inc
+++ b/includes/database/pgsql/query.inc
@@ -173,3 +173,13 @@ public function execute() {
     return $stmt->rowCount();
   }
 }
+
+class SelectQuery_pgsql extends SelectQuery {
+
+  public function orderRandom() {
+    $alias = $this->addExpression('RANDOM()', 'random_field');
+    $this->orderBy($alias);
+    return $this;
+  }
+
+}
diff --git a/includes/database/select.inc b/includes/database/select.inc
index a4c4ed3e40c74c672e33d8fb2130283d6d2d3104..55eecf5868ccfe2e3801fd210a040325bb40d096 100644
--- a/includes/database/select.inc
+++ b/includes/database/select.inc
@@ -347,6 +347,28 @@ public function addJoin($type, $table, $alias = NULL, $condition = NULL, $argume
    */
   public function orderBy($field, $direction = 'ASC');
 
+  /**
+   * Orders the result set by a random value.
+   *
+   * This may be stacked with other orderBy() calls. If so, the query will order
+   * by each specified field, including this one, in the order called. Although
+   * this method may be called multiple times on the same query, doing so
+   * is not particularly useful.
+   *
+   * Note: The method used by most drivers may not scale to very large result
+   * sets. If you need to work with extremely large data sets, you may create
+   * your own database driver by subclassing off of an existing driver and
+   * implementing your own randomization mechanism. See
+   *
+   * http://jan.kneschke.de/projects/mysql/order-by-rand/
+   *
+   * for an example of such an alternate sorting mechanism.
+   *
+   * @return
+   *   The called object
+   */
+  public function orderRandom();
+
   /**
    * Restricts a query to a given range in the result set.
    *
@@ -643,6 +665,11 @@ public function orderBy($field, $direction = 'ASC') {
     return $this;
   }
 
+  public function orderRandom() {
+    $this->query->orderRandom();
+    return $this;
+  }
+
   public function range($start = NULL, $length = NULL) {
     $this->query->range($start, $length);
     return $this;
@@ -1182,6 +1209,12 @@ public function orderBy($field, $direction = 'ASC') {
     return $this;
   }
 
+  public function orderRandom() {
+    $alias = $this->addExpression('RAND()', 'random_field');
+    $this->orderBy($alias);
+    return $this;
+  }
+
   public function range($start = NULL, $length = NULL) {
     $this->range = func_num_args() ? array('start' => $start, 'length' => $length) : array();
     return $this;
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 8c1bb1dc57097fa06eabfd91659a758be05e13c6..e12431a30d3962f6f245b780b0d58a663e82b7c4 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -1400,6 +1400,55 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
     $this->assertEqual($names[1], 'Ringo', t('Second query returned correct second name.'));
     $this->assertEqual($names[2], 'Ringo', t('Third query returned correct name.'));
   }
+
+  /**
+   * Test that random ordering of queries works.
+   *
+   * This is a non-deterministic query. That is, it is not guaranteed to pass
+   * 100% of the time.  Random numbers are like that. Instead, we take two sets
+   * of random selects.  By the laws of probability, the average of each set
+   * should be roughly the average of the data set being selected from and
+   * roughly the same each time through, provided that the original data set
+   * is evenly distributed. Because we know that ours is, this test should pass
+   * correctly 99% of the time. It is not possible to unit test for that other
+   * 1% successfully, so that will have to do.
+   */
+  function testRandomOrder() {
+    $sets = 2;
+    $runs = 50;
+
+    $ids = array();
+    $ids = array();
+
+    $max = db_query("SELECT MAX(id) FROM {test}")->fetchField();
+    $min = db_query("SELECT MIN(id) FROM {test}")->fetchField();
+
+    $ideal_average = ($min + $max) / 2;
+    $allowed_deviation = ($max - $min) / 4;
+
+    for ($i = 0; $i < $sets; ++$i) {
+      for ($j = 0; $j < $runs; ++$j) {
+        $ids[$i][] = db_select('test', 't')
+          ->fields('t', array('id'))
+          ->range(0, 1)
+          ->orderRandom()
+          ->orderBy('id')
+          ->execute()
+          ->fetchField();
+      }
+    }
+
+    for ($i = 0; $i < $sets; ++$i) {
+      $found_average[$i] = array_sum($ids[$i]) / count($ids[$i]);
+      $deviation = abs($found_average[$i] - $ideal_average);
+      $this->assertTrue($deviation <= $allowed_deviation, t('Random ids are within allowed deviation.'));
+    }
+
+    for ($i = 1; $i < $sets; ++$i) {
+      $deviation = abs($found_average[$i] - $found_average[$i-1]);
+      $this->assertTrue($deviation <= $allowed_deviation, t('Random ids are within allowed deviation from each other.'));
+    }
+  }
 }
 
 /**
@@ -2897,7 +2946,7 @@ class DatabaseExtraTypesTestCase extends DrupalWebTestCase {
              'description' => t('Test Time field'),
              'type' => 'time',
              'not null' => FALSE,
-	       ),
+           ),
          ),
        );
        $ret = array();