2011-04-24 35 views
5

¿Cómo puedo escribir una sub consulta SQL usando la sintaxis de pastel? Sé cómo codificar una consulta simple, pero no puedo manejar las subconsultas.CakePHP y subconsulta

Ésta es la consulta original:

SELECT Assumption.id, Referee.id, Referee.first_name, Referee.second_name 
FROM referees AS Referee 
INNER JOIN (

    SELECT a.id, a.referee_id 
    FROM assumptions a 
    WHERE a.season_id =7 
) AS Assumption ON Referee.id = Assumption.referee_id 

Respuesta

6

Puesto que usted no entiende la sintaxis, esta es la consulta real:

$records = $this->Referee->find('all', array(
       'fields' => array(
        'Assumption.id', 'Referee.id', 'Referee.first_name', 'Referee.second_name' 
        ), 
       'joins' => array(
        array(
         'table' => 'assumptions', 
         'alias' => 'Assumption', 
         'type' => 'INNER', 
         'foreignKey' => false, 
         'conditions' => array('Referee.id = Assumption.referee_id', 'Assumption.season_id = 7'), 
         ), 
       ), 
      ) 
     ); 

que produce esta consulta:

SELECT 
    `Assumption`.`id`, 
    `Referee`.`id`, 
    `Referee`.`first_name`, 
    `Referee`.`second_name` 
FROM `referees` AS `Referee` 
INNER JOIN assumptions AS `Assumption` 
    ON (`Referee`.`id` = `Assumption`.`referee_id` 
     AND `Assumption`.`season_id` = 7) 

que proporcionan los resultados que está buscando.

salida

muestra:

Array 
(
    [0] => Array 
     (
      [Assumption] => Array 
       (
        [id] => 1 
        [0] => Array 
         (
          [id] => 1 
          [season_id] => 7 
          [referee_id] => 1 
          [name] => SomeAssumpton 
         ) 

       ) 

      [Referee] => Array 
       (
        [id] => 1 
        [first_name] => Ref 
        [second_name] => one 
       ) 

     ) 

) 
+0

Esta producen consulta sencilla, que producen la respuesta unusefull. Debería reproducir exactamente esa subconsulta. –

+0

Escribí el código porque no podías entender la sintaxis. Producirá los resultados que estás buscando. –

+1

Si desea que su subconsulta EXACTA, la única otra opción que tienes es utilizar: '$ this-> Referee-> query ('{SU sub-consulta AQUÍ}');' como CakePHP no tiene una sintaxis para las subconsultas forma en que quieres escribirlos. –

1

así que después de lo que parecieron años (varias horas) y la lectura fuente de pastel ... si quieres simplemente escriba su subconsulta en sus condiciones de pastel ...

que utiliza stdClass php no es una entrada de la matriz ... se acaba de volcar su "valor" en la consulta ...

$subquery = new stdClass(); 
    $subquery->type = "expression"; 
    $subquery->value = "Product.id IN (select product_id from product_categories where category_id='$category_id' or belongs_to='$category_id')"; 

    $options['conditions'][] = $subquery; <- dump the class into your conditions array! 

hacer consulta normal $ this-> table-> find ('all', $ options)

Ejemplo: (torta normal con quickfix subconsulta) respuesta

//only from my vendor 
    $options['conditions']['collection_id'] = $vendor_id; 

    //inner join to CollectionProduct 
    $options['joins'][0] = array(
     "table" => "collection_products", 
     "alias" => "CollectionProduct", 
     "type" => "INNER", 
     "conditions" => array(
      "Product.id = CollectionProduct.product_id", 
     ), 
    ); 

    //show only from current category 
    if ($category_id) { 
     $subquery = new stdClass(); 
     $subquery->type = "expression"; 
     $subquery->value = "Product.id IN (select product_id from product_categories where category_id='$category_id' or belongs_to='$category_id')"; 
     $options['conditions'][] = $subquery; 
    } else { 
     //get 18 random items... no category selected? 
     $options['limit'] = 18; 
    } 

    return $this->find('all', $options); 
+2

Eso es lo que sucede detrás de las escenas, pero la forma correcta de hacerlo sería seguir las instrucciones [en el libro de cocina] (http://book.cakephp.org/view/1030/Complex-Find-Conditions). –

+1

si ve el enlace y baja a "Subconsultas" verá una gran sobrecarga para generar la línea de sql que se muestra arriba y esto es corto y agradable. hay muchas preguntas que el pastel "no puede" hacer. Si haces subconsultas multinucleadas imagina lo horrible que sería el libro de cocina. – duante

+1

La única razón por la que este método ahorra espacio es porque la subconsulta se escribió explícitamente. El OP específicamente declaró que querían usar la metodología del pastel. La ruta más corta si no le importa es simplemente usar $ this-> Model-> query(). De acuerdo, el método de la guía es largo, pero no ayuda que el autor del código de ejemplo no haya hecho el mejor trabajo. –

2

de cdburgess es correcto para esta situación; resuelve el problema de la manera más simple y directa.

Dicho esto, al resolver la cuestión genérica de la realización de una subconsulta, el libro de cocina documenta la preferred solution to the subquery problem. No es muy elegante, pero es la forma en que la guía dice que lo haga.

o simplemente puede ser muy cuidadosos y sólo hacer una $ this-> Modelo-> query().

+0

No es correcto si no responde la pregunta.Dar una respuesta no relacionada no hace que la respuesta sea correcta. Si la pregunta era, ¿cómo consulto una relación en cakephp ?, entonces esa sería la respuesta correcta. – Nemesis02

+0

Chuck Burgess definitivamente responde la pregunta del OP: su método incluso produce los resultados correctos de una manera más eficiente. No hay razón para ser exigente con respecto a si utilizó una subconsulta si hay una mejor solución. –

+1

Es más que probable que su pregunta diga que es solo un ejemplo de la situación que se le está presentando. La consulta probablemente sería más compleja que eso, como la mía, por ejemplo. Tengo tres modelos, a, b y c, a tiene muchos a muchos con b que contiene un tipo con una tabla dinámica, y c tiene una relación muchos a uno con a. Si necesitaba un informe donde el tipo de c es un cierto valor, cuando lo haga, devolverá duplicados, 1 para cada relación, porque tuvo que cargarlo antes de verificar el tipo. Una verdadera subconsulta como la que describió podría resolver eso, no la respuesta que dijo Chuck. – Nemesis02