mysql cakephp cakephp-2.x

mysql - CakePHP: ¿Cómo puedo usar una operación de "HAVING" al crear consultas con el método de búsqueda?



cakephp-2.x (5)

Aquí hay otra idea que no resuelve el problema de la paginación, pero está limpia ya que simplemente reemplaza el comando de búsqueda en AppModel. Simplemente agregue un grupo y un elemento que tenga a su consulta y esto se convertirá en una cláusula HAVING.

public function find($type = ''first'', $query = array()) { if (!empty($query[''having'']) && is_array($query[''having'']) && !empty($query[''group''])) { if ($type == ''all'') { if (!is_array($query[''group''])) { $query[''group''] = array($query[''group'']); } $ds = $this->getDataSource(); $having = $ds->conditions($query[''having''], true, false); $query[''group''][count($query[''group'']) - 1] .= " HAVING $having"; CakeLog::write(''debug'', ''Model->find: out query='' . print_r($query, true)); } else { unset($query[''having'']); } } return parent::find($type, $query); }

Lo encontré aquí

https://groups.google.com/forum/?fromgroups=#!topic/tickets-cakephp/EYFxihwb55I

Estoy tratando de usar la cláusula "HAVING" en una consulta SQL usando el método CakePHP paginate ().

Después de algunas búsquedas, parece que esto no se puede lograr a través de los métodos paginate () / find () de Cake.

El código que tengo se ve algo como esto:

$this->paginate = array( ''fields'' => $fields, ''conditions'' => $conditions, ''recursive'' => 1, ''limit'' => 10, ''order'' => $order, ''group'' => ''Venue.id'');

Uno de los campos $ es un alias "distance". Quiero agregar una consulta para cuando la distancia <25 (por ejemplo, HAVING distancia <25).

Hasta ahora he visto dos soluciones alternativas, lamentablemente ninguna de ellas satisface mis necesidades. Los dos que he visto son:

1) Agregar la cláusula HAVING en la opción "grupo". por ejemplo, ''group'' => ''Venue.id HAVING distance < 25'' . Parece que esto no funciona cuando se usa junto con la paginación, ya que desordena la consulta de conteo inicial que se realiza. (es decir, intenta SELECT distinct(Venue.id HAVING distance < 25) que obviamente es una sintaxis no válida.

2) Agregar la cláusula HAVING después de la condición WHERE (por ejemplo, WHERE 1 = 1 HAVING field > 25 ) Esto no funciona como parece que la cláusula HAVING debe aparecer después de la declaración del grupo que Cake está colocando después de la condición WHERE en la consulta genera.

¿Alguien sabe de una manera de hacer esto con el método find () de CakePHP? No quiero usar la consulta () ya que eso implicaría una gran cantidad de trabajo y también significa que necesitaría implementar mi propia lógica de paginación.

Gracias por adelantado


Hay que ponerlo con las condiciones del grupo. Me gusta esto

$this->find(''all'', array( ''conditions'' => array( ''Post.length >='' => 100 ), ''fields'' => array( ''Author.id'', ''COUNT(*) as Total'' ), ''group'' => array( ''Total HAVING Total > 10'' ) ));

Espero te ayude


Según el manual , CakePHP / 2 admite having por fin. Se agregó como parámetro de matriz de búsqueda en la versión 2.10.0, released el 22 de julio de 2017.

De la Guía de Migración 2.10 :

Model::find() ahora admite having y lock opciones que le permiten agregar HAVING y FOR UPDATE cláusulas de bloqueo a sus operaciones de búsqueda.


Solo tuve el mismo problema. Lo sé, uno no debe modificar el código interno, pero si abre el PaginatorComponent y modifica la línea 188:

$count = $object->find(''count'', array_merge($parameters, $extra));

a esto:

$count = $object->find( ''count'', array_merge(array("fields" => $fields),$parameters, $extra) );

Todo será arreglado. Podrás agregar tu cláusula HAVING al ''grupo'' y el COUNT (*) no será un problema.

O bien, hacer línea:

$count = $object->paginateCount($conditions, $recursive, $extra);

para incluir los $fields :

$count = $object->paginateCount($fields,$conditions, $recursive, $extra);

Después de eso, puedes "anular" el método en el Modelo y asegurarte de incluir los campos $ en el buscador () ¡y listo! = P


Utilicé el siguiente truco para agregar mi propia cláusula HAVING al final de mi cláusula WHERE. El método "dbo-> expresión ()" se menciona en la documentación de la subconsulta de pastel.

function addHaving(array $existingConditions, $havingClause) { $model = ''User''; $db = $this->$model->getDataSource(); // Two fun things at play here, // 1 - mysql doesn''t allow you to use aliases in WHERE clause // 2 - Cake doesn''t allow a HAVING clause separate from a GROUP BY // This expression should go last in the WHERE clause (following the last AND) $taut = count($existingConditions) > 0 ? ''1 = 1'' : ''''; $having = $db->expression("$taut HAVING $havingClause"); $existingConditions[] = $having; return $existingConditions; }