doudao5287 2009-07-17 18:58
浏览 109
已采纳

MySQL随机行按列名排序

Original Question:

I am currently using Zend Framework with Zend_Db_*, and I am selecting three random rows from a table:

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

Where $category is a Zend_Db_Table_Row. I would like to grab three random rows, but have those three rows ordered by the column named name.

Changing the ->order() to the following had no effect:

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

As the entries are still showing up un-ordered, and still random.

Zend Framework solutions appreciated, but I can adapt other solutions to fit within my project.


I am aware of the scaling issues with using RAND(), the database will never get big enough for this to become an issue, the day it does I won't have to worry about maintaining it, the robots will, as I'll be long dead! :-P


Answer

For those wondering how this was ultimately completed using Zend_Db_Select, this is what it came down to use a sub-select within the Zend_Db_Select (I was using $category->findDefault_Model_projects() to find the dependent rowset, but that does not allow me to use the select() as a subselect until ZF-6461 fixes the issue, I am stuck with what I have):

$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();

The generated SQL is:

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

From there $projects contains the standard row set which can be iterated over much like any other database queries, the only thing it does not do is stick it in a table specific row/rowset class, which could have its downsides.

  • 写回答

4条回答 默认 最新

  • douna6802 2009-07-17 19:59
    关注

    Your initial solution is not correct because this query will generate a random value for each row and the order the rows based on it, sorting by name only if random values are equal (which is highly improbable).

    The problem can be solved with a subquery like the one below

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

    I'm leaving to you the task of translating this into Zend_Db language.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 急matlab编程仿真二阶震荡系统
  • ¥20 TEC-9的数据通路实验
  • ¥15 ue5 .3之前好好的现在只要是激活关卡就会崩溃
  • ¥50 MATLAB实现圆柱体容器内球形颗粒堆积
  • ¥15 python如何将动态的多个子列表,拼接后进行集合的交集
  • ¥20 vitis-ai量化基于pytorch框架下的yolov5模型
  • ¥15 如何实现H5在QQ平台上的二次分享卡片效果?
  • ¥15 python爬取bilibili校园招聘网站
  • ¥30 求解达问题(有红包)
  • ¥15 请解包一个pak文件