Pergunta

Original Pergunta:

Atualmente, estou usando Zend Framework com Zend_Db_*, e eu estou selecionando três linhas aleatórias de uma tabela:

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

Onde $category é um Zend_Db_Table_Row. Gostaria de pegar três linhas aleatórias, mas ter essas três linhas ordenada pelo name coluna chamada.

A alteração do ->order() ao seguinte não teve qualquer efeito:

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

Como as entradas ainda estão aparecendo, e ainda aleatória ordenou-un.

soluções Zend Framework apreciado, mas eu posso adaptar outras soluções para caber dentro do meu projeto.


Estou ciente dos problemas de escala com o uso de RAND (), o banco de dados nunca vai ficar grande o suficiente para que isso se torne um problema, o dia que ele faz não terá que se preocupar sobre como manter isso, os robôs irá, como Eu estarei morto há muito tempo! :-P


Resposta

Para aqueles que querem saber como isso foi finalmente concluída usando Zend_Db_Select, é isso que ele desceu para usar uma sub-selecionar dentro do Zend_Db_Select (eu estava usando $category->findDefault_Model_projects() para encontrar o conjunto de linhas dependentes, mas que não permite que eu use o select () como um subselect até ZF-6461 correções o problema, eu estou preso com o que eu tenho):

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

O SQL gerado é:

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

A partir daí $ projectos contém o conjunto de linhas padrão que pode ser iterado bem como quaisquer outras consultas de banco de dados, a única coisa que não faz é colocá-lo em uma classe linha de tabela específica / conjunto de linhas, o que pode ter suas desvantagens.

Foi útil?

Solução

A sua solução inicial não é correto porque esta consulta irá gerar um valor aleatório para cada linha ea ordem as linhas com base nele, a classificação por nome somente se valores aleatórios são iguais (o que é altamente improvável).

O problema pode ser solucionado com uma subconsulta como a abaixo

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

Eu estou deixando-lhe a tarefa de traduzir isso em linguagem Zend_Db.

Outras dicas

$subQuery = $this->select()->from('picture')->order(new Zend_Db_Expr('RAND()'))->limit(count($this->selectAll()));
$select->setIntegrityCheck(false)
       ->from($subQuery);

Este é o que eu fiz e ele funciona. Felicidades!

Porque não basta criar uma função de conjunto de linhas subclasse que classifica os dados pelo nome?

Tente isto:

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

que funciona para mim aqui assim que deve funcionar para você também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top