cakephp 2.x使用' NOT IN'在子查询中

时间:2015-05-05 22:40:58

标签: mysql cakephp orm

我有这个小的mysql查询(它返回没有1,3,5状态的元素):

SELECT DISTINCT number FROM records WHERE number NOT IN
( SELECT number FROM records WHERE state_id = 1 or state_id = 3 or state_id = 5)

在cakephp中我不擅长子查询,但我能够做到:

    $conditionsSubQuery['`Record2`.`state_id`'] = array(1,3,5);

      $db = $this->Record->State->getDataSource();

      $subQuery = $db->buildStatement(
    array(
        'fields'     => array('`Record2`.`number`'),
        'table'      => $db->fullTableName($this->Record),
        'alias'      => 'Record2',
        'limit'      => null,
        'offset'     => null,
        'joins'      => array(),
        'conditions' => $conditionsSubQuery,
        'order'      => null,
        'group'      => null
    ),
    $this->Record
);

      $subQuery = ' `Record`.`number` NOT IN (' . $subQuery . ') ';

      $subQueryExpression = $db->expression($subQuery);

     $conditions[] = $subQueryExpression;



     $subQuery=$this->Record->find('first', compact('conditions'),
             //array('recursive'=>0),
             array('fields'=>array('Record.state_id')
             ));

也许我不理解一些好东西,但是获得相同结果需要大量代码真的很烦人,我知道核心mysql有$ this->查询 但有没有一种方法可以通过恰当使用的条件获得相同的结果'?或者,cakephp不支持' NOT IN'那就是为什么没有更简单的方法?

UPDATE1: 查询方案如下:

(1, 'A', 1),
(2, 'A', 2),
(3, 'B', 3),
(4, 'C', 2),
(5, 'B', 1),

mysql查询的结果只返回C,因为B的值也是3,与A相同。 没有'不在' B也被返回(因为也有1个值)。

我尽量让它尽可能清晰,我添加一些额外的值来显示哪个适合结果: http://www.sqlfiddle.com/#!9/cc92a/1

2 个答案:

答案 0 :(得分:2)

除非我误解了您的原始查询,否则根本不需要使用子查询。

在CakePHP中,您可以在查找条件中使用关键字NOT来应用查询的NOT部分;处理IN部分只需传递一系列选项: -

$this->Record->find(
    'all',
    array(
        'fields' => array(
            'number'
        )
        'conditions' => array(
            'NOT' => array(
                'state_id' => array(1, 3, 5)
            )
        ),
        'group' => array(
            'number'
        )
    )
);

我使用fields将响应限制在number列,并使用group仅返回不同的结果。

否则,要在Cake 2中使用子查询,最简单的方法是单独执行子查询,然后在主查询中使用该响应。 Cake 3的新ORM是更好的子查询设置。

<强>更新

根据您在问题中更新的示例,我认为实现您希望它执行两个查询的最简单方法。首先获取您不想包含的记录号($exclude),然后使用该结果将其从结果查询中排除: -

$exclude = $this->Record->find(
    'list',
    array(
        'fields' => array(
            'id', 'number'
        ),
        'conditions' => array(
            'state_id' => array(1, 3, 5)
        ),
        'group' => array(
            'number'
        )
    )
);

$result = $this->Record->find(
    'all',
    array(
        'fields' => array(
            'number'
        )
        'conditions' => array(
            'NOT' => array(
                'number' => $exclude
            )
        ),
        'group' => array(
            'number'
        )
    )
);

答案 1 :(得分:0)

$coupons = $this->Record->find('list',
    array('conditions'=>('Record.id NOT IN (select record_id from record_2)')
));

这就是我所做的。 希望对您有所帮助。