2011-04-24 72 views
5

如何使用Cake语法编写SQL子查询? 我知道如何编写简单的查询,但我无法处理子查询。CakePHP和子查询

这是原始查询:

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 

回答

6

既然你听不懂的语法,这是实际的查询:

$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'), 
         ), 
       ), 
      ) 
     ); 

将会产生这个查询:

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) 

其中提供您正在寻找的结果。

输出示例:

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

这产生简单的查询,产生不必要的响应。我应该重现那个子查询。 – 2011-04-24 18:38:56

+0

由于您无法理解语法,因此我为您编写了代码。它会产生你正在寻找的结果。 – 2011-04-24 22:34:07

+1

如果你想要你的EXACT子查询,你唯一的其他选择就是使用:'$ this-> Referee-> query('{你的SUB-QUERY HERE}');'因为CakePHP没有子查询语法你想要写他们的方式。 – 2011-04-25 01:54:19

1

打完似乎像年(几个小时),阅读蛋糕源...如果你想简单地键入您的子查询到你的蛋糕条件......

它使用PHP stdClass已经不是一个数组项...它只会转储你的“价值”进入查询......

$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! 

做普通查询 $这个 - >表 - >找到(“所有”, $选项)

实例:(正常蛋糕,子查询的quickfix)

//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

这就是幕后发生的事情,但正确的做法是遵循[食谱手册]中的说明(http://book.cakephp.org/view/1030/Complex-Find-Conditions)。 – 2011-10-07 19:31:49

+1

如果你转到你的链接并进入“子查询”,你将看到巨大的开销,生成上面显示的一行SQL,这是简短而甜蜜的。有很多查询“不能”的蛋糕。如果你做多嵌套子查询想象食谱会有多可怕。 – duante 2011-10-07 21:39:17

+1

此方法节省空间的唯一原因是因为子查询是明确写入的。 OP特别声明他们想要使用蛋糕方法。如果你不关心的话,最简单的路线是简单地使用$ this-> Model-> query()。同意,指南的方法很长,但这对示例代码的作者没有做出最大的工作没有帮助。 – 2011-10-07 21:55:42

2

cdburgess的答案是这种情况的正确的;它以最简单,最直接的方式解决问题。

这就是说,当解决执行子查询的一般问题时,食谱记录了preferred solution to the subquery problem。这不是很优雅,但是这是指南所说的做法。

或者你可以非常小心,只要做一个$ this-> Model-> query()。

+0

如果它不回答问题,这是不正确的。给予无关的答案并不能使答案正确。如果问题是,我如何查询cakephp中的关系,那么这将是正确的答案。 – Nemesis02 2016-01-26 17:36:16

+0

查克伯吉斯绝对回答OP的问题 - 他的方法甚至以更有效的方式产生正确的结果。如果有更好的解决方案,没有理由对它是否使用子查询进行挑剔。 – 2016-01-26 17:50:27

+1

他的问题很可能只是他被呈现的情况的一个例子。查询可能会比这更复杂,比如我的例子。我有三个模型,a,b和c,a有多对多的b,它包含一个带有数据透视表的类型,c与a有多对一的关系。如果我需要一个报告,其中c的类型是一个特定的值,那么当它执行报告时,它将返回重复值,对于每个关系都会返回1,因为它必须在检查类型之前加载它。像他描述的一个真正的子查询可以解决这个问题,而不是查克说的答案。 – Nemesis02 2016-01-27 20:47:20