我已经坚持了大约 10 个小时
我需要使用这个查询(ORDER BY RAND 的优化版本)
public function findAllRandom()
{
return $this->getEntityManager()
->createQuery(
'SELECT p FROM GabrielUploadBundle:Image p WHERE RAND() < 0.0001 ORDER BY RAND() LIMIT 20')
->getResult();
}
当然,因为我使用的是 DQL,所以我需要实现 RAND() 函数
<?php
namespace Gabriel\UploadBundle\DoctrineFunctions;
use Doctrine\ORM\Query\Lexer;
/**
* RandFunction ::= "RAND" "(" ")"
*/
class Rand extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
{
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'RAND()';
}
}
//配置.yml
orm:
(...)
dql:
numeric_functions:
Rand: Gabriel\UploadBundle\DoctrineFunctions\Rand
问题是我一直收到这个错误:
[Syntax Error] line 0, col 77: Error: Expected end of string, got '('
RAND()源码出处:
如何从配置中添加:
http://symfony.com/doc/current/cookbook/doctrine/custom_dql_functions.html
DQL添加函数示例
http://punkave.com/window/2012/07/24/for-the-php-crowd-adding-custom-functions-to-doctrine-2-dql
编辑: 经过进一步研究,我发现 dql 不支持按函数排序: 来源: http://docs.doctrine-project.org/en/2.1/reference/faq.html#can-i-sort-by-a-function-for-example-order-by-rand-in-dql
要解决这个问题,可以添加 HIDDEN 值
public function findAllRandom()
{
return $this->getEntityManager()
->createQuery(
'SELECT p,RAND() AS HIDDEN rand FROM GabrielUploadBundle:Image p ORDER BY rand')
->getResult();
}
但由于某些原因它不适用于 WHERE 子句
public function findAllRandom()
{
return $this->getEntityManager()
->createQuery(
'SELECT p,RAND() AS HIDDEN rand FROM GabrielUploadBundle:Image p WHERE rand < 0.00001 ORDER BY rand')
->getResult();
}
where 子句的解决方案将不胜感激,每个人都知道使用 ORDER BY RAND() 函数会降低服务器速度(在我们的例子中甚至会导致服务器崩溃)
最佳答案
您可以使用来自 Controller 的 native SQL 查询
$em = $this->getDoctrine()->getManager();
$connection = $em->getConnection();
$statement = $connection->prepare("SELECT * FROM Image WHERE RAND()<(SELECT ((10/COUNT(*))*10) FROM Image) ORDER BY RAND() LIMIT 10");
$statement->execute();
$images = $statement->fetchAll();
基准测试结果 http://www.warpconduit.net/2011/03/23/selecting-a-random-record-using-mysql-benchmark-results/
关于mysql - 在 Doctrine2 中使用 SQL 中的 RAND() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23112845/