Случайные строки MySQL, отсортированные по имени столбца - PullRequest
2 голосов
/ 17 июля 2009

Оригинальный вопрос:

В настоящее время я использую Zend Framework с Zend_Db_* и выбираю три случайные строки из таблицы:

$category->getTable()->select()->order(new Zend_Db_Expr('RAND()'))->limit('3')

Где $category является Zend_Db_Table_Row. Я хотел бы получить три случайных строки, но эти три строки упорядочены по столбцу с именем name.

Изменение ->order() на следующее ничего не дало:

->order(array(new Zend_Db_Expr('RAND()'), 'name ASC'))

Поскольку записи по-прежнему отображаются неупорядоченными и случайными.

Решения Zend Framework приветствуются, но я могу адаптировать другие решения для своего проекта.


Я знаю о проблемах масштабирования с использованием RAND (), база данных никогда не станет достаточно большой, чтобы это стало проблемой, в тот день, когда это произойдет, мне не придется беспокоиться о ее обслуживании, роботы, как Я буду давно мертв! : -Р


Ответ

Для тех, кто интересуется, как это в конечном итоге было завершено с использованием Zend_Db_Select, это то, что он использовал, чтобы использовать подвыбор в Zend_Db_Select (я использовал $category->findDefault_Model_projects(), чтобы найти зависимый набор строк, но это не позволяет мне использовать select () в качестве подвыбора, пока ZF-6461 не исправит проблему, я застрял с тем, что у меня есть):

$projects = new Default_Model_Projects();
$subselect = $projects->select()->order(new Zend_Db_Expr('RAND()'))->limit('3')->where('cid = ?', $category->id, Zend_Db::INT_TYPE);
$db = $projects->getAdapter();
$select = $db->select()->from(array("c" => new Zend_Db_Expr("({$subselect})")))->order('name');

$stmt = $select->query();
$projects = $stmt->fetchAll();

Сгенерированный SQL:

SELECT `c`.* FROM (SELECT `projects`.* FROM `projects` WHERE (cid = 1) ORDER BY RAND() LIMIT 3) AS `c` ORDER BY `name` ASC

Исходя из этого, $ projects содержит стандартный набор строк, который можно повторять практически так же, как и любые другие запросы к базе данных, единственное, что он не делает, - это вставляет его в определенный класс таблицы / rowset, у которого могут быть свои недостатки.

Ответы [ 4 ]

4 голосов
/ 17 июля 2009

Ваше первоначальное решение неверно, так как этот запрос будет генерировать случайное значение для каждой строки и порядок строк на его основе, сортируя по имени, только если случайные значения равны (что крайне маловероятно).

Проблема может быть решена с помощью подзапроса, подобного приведенному ниже

select * from (select * from categories order by rand() limit 3) c order by name

Я оставляю вам задачу перевести это на язык Zend_Db.

1 голос
/ 21 декабря 2011
$subQuery = $this->select()->from('picture')->order(new Zend_Db_Expr('RAND()'))->limit(count($this->selectAll()));
$select->setIntegrityCheck(false)
       ->from($subQuery);

Это то, что я сделал, и это работает. Ура! * * 1002

0 голосов
/ 18 июля 2009

Попробуйте это:

$select = $this->select();
$select->order('RAND(), name');
$select->limit(3);
return $this->fetchAll($select);

Это работает для меня здесь, поэтому должно работать и для вас.

0 голосов
/ 18 июля 2009

Почему бы просто не создать функцию подкласса Rowset, которая сортирует данные по имени?

...