【问题标题】:MySQL random rows sorted by a column nameMySQL 随机行按列名排序
【发布时间】:2009-07-17 18:58:20
【问题描述】:

原问题:

我目前正在使用带有Zend_Db_* 的 Zend Framework,并且我正在从表中选择三个随机行:

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

其中$categoryZend_Db_Table_Row。我想随机抓取三行,但是这三行按名为name 的列排序。

->order() 更改为以下内容无效:

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

由于条目仍然显示为无序,并且仍然是随机的。

Zend 框架解决方案值得赞赏,但我可以调整其他解决方案以适应我的项目。


我知道使用 RAND() 的扩展问题,数据库永远不会变得足够大而成为问题,当它发生的那一天我不必担心维护它,机器人会,因为我会死很久的! :-P


回答

对于那些想知道这最终是如何使用 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 包含可以像任何其他数据库查询一样迭代的标准行集,它唯一不做的是将其粘贴在特定于表的行/行集类中,这可能有其缺点。

【问题讨论】:

  • 您是否尝试使用 Zend_Db_Profiler 查看生成的请求? (见framework.zend.com/manual/en/zend.db.profiler.html
  • @Pascal:我今天回去工作,并在 SQL 上使用了 __toString():SELECT projects.* FROM projects WHERE (cid = 1) ORDER BY RAND() , name ASC LIMIT 3 所以是的,我认为我想要的正在生成。

标签: php mysql zend-framework zend-db zend-db-table


【解决方案1】:

您的初始解决方案不正确,因为此查询将为每一行生成一个随机值并根据它对行进行排序,仅当随机值相等时才按名称排序(这是极不可能的)。

这个问题可以通过如下子查询来解决

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

我将把它翻译成 Zend_Db 语言的任务留给你。

【讨论】:

  • 当我周一回去工作时,我会测试这个解决方案。我赞成让我知道为什么我的不起作用!
  • 这很好用,使用 Zend 框架 Zend_Db_Select 类,查询最终是: SELECT c.* FROM (SELECT projects.* FROM projects WHERE (cid = 1) ORDER BY RAND() LIMIT 3) AS c ORDER BY name ASC
【解决方案2】:
$subQuery = $this->select()->from('picture')->order(new Zend_Db_Expr('RAND()'))->limit(count($this->selectAll()));
$select->setIntegrityCheck(false)
       ->from($subQuery);

这就是我所做的,并且有效。干杯!

【讨论】:

    【解决方案3】:

    为什么不直接创建一个按名称对数据进行排序的行集子类函数?

    【讨论】:

      【解决方案4】:

      试试这个:

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

      这对我有用,所以它也应该对你有用。

      【讨论】:

      • 如果您查看我的帖子,这正是我所做的,除了我使用 Zend_DB_Expr 和一个数组将其传递给 order(),如果您使用数据库表达式。生成的 SQL 完全一样: SELECT projects.* FROM projects WHERE (cid = 1) ORDER BY RAND(), name ASC LIMIT 3
      • 问题是它不起作用,它没有ORDER BY RAND()然后限制为3,然后按名称排序。
      猜你喜欢
      • 2013-06-12
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 2019-08-24
      • 2011-06-18
      • 1970-01-01
      相关资源
      最近更新 更多