【问题标题】:CakePHP X hasMany Y, find X that has Y.name = "value1" AND at the same time has Y.name = "value2"CakePHP X hasMany Y, 找到有 Y.name = "value1" AND 同时有 Y.name = "value2" 的 X
【发布时间】:2012-05-18 20:23:35
【问题描述】:

所以我的模型关联如下:

人有很多奖

人员列:id、name 奖励栏:id、person_id、name

所以人们可以有很多奖项,但我只想检索那些同时获得两个不同奖项的特定人。有没有办法通过 find 方法实现这一点?

【问题讨论】:

    标签: mysql cakephp


    【解决方案1】:
    $persons = $this->Person->find('all', array(
                               'recursive' => -1,
                               'conditions' => array(
                                  'AND' => array('Award.name' => 'Award 1', 'Award.name' => 'Award 3')
                                ),
                               'joins' => array(
                                    array(
                                       'table' =>'awards',
                                       'alias' => 'Award',
                                       'type' => 'LEFT',
                                       'conditions' => 'Award.person_id = person.id'
                                     )
                                )
                          )
                     );
    

    【讨论】:

    • 我相信这就是我要找的东西,很快就会测试它。谢谢
    • 我认为这不会起作用,因为它会产生IN (value1, value2) 条件。这可以在OR 中简化,这不是@user1399007 想要的。他说他想要同时获得这两个奖项的用户。
    • 在这种情况下,这不是我要找的:/。我希望它是一个 AND 语句。
    • @user1399007 在我更新的答案中获取 AND 声明,供您参考,我以前和当前的代码都做同样的工作
    【解决方案2】:

    查看页面末尾的subqueries。您基本上需要一个子查询,因为您需要查询 Award 表两次以匹配 value1 和 value2。


    编辑: 示例代码

    $conditionsSubQuery['`Award`.`name`'] = 'value2';
    $dbo = $this->Person->getDataSource();
    $subQuery = $dbo->buildStatement(
        array(
            'fields' => array( '`Person2`.`id`'),
            'table' => $dbo->fullTableName($this->Person),
            'alias' => 'Person2',
            'limit' => null,
            'offset' => null,
            'joins' => array(),
            'conditions' => $conditionsSubQuery,
            'order' => null,
            'group' => null
        ),
        $this->Person
    );
    $subQuery = ' `Person`.`id` IN (' . $subQuery . ') ';
    $subQueryExpression = $dbo->expression($subQuery);
    $conditions[] = array('Award.name' => 'value1');
    $conditions[] = $subQueryExpression;
    $this->Person->find('all', compact('conditions'));
    

    我没有测试过它,它可能不起作用,但你明白了。


    编辑 2: 回答您的评论

    所以基本上你想要的 SQL 结果是

    select 
        users.id 
    from 
        users 
    left join 
        awards 
    where 
        awards.name in ('award1', 'award2', 'award3', 'award4') 
    group by 
        awards.name 
    having 
        count(awards.name) = 4
    

    要做到这一点,你可以这样做:

    $awards = array('award1', 'award2', 'award3', 'award4');
    
    $this->Person->find(
        'all',
        array(
            'joins' => array(
                array(
                   'table' =>'awards',
                   'alias' => 'Award',
                   'type' => 'LEFT',
                   'conditions' => 'Award.person_id = person.id'
                 )
            ),
            'conditions' => array(
                'Award.name' => $awards,
            ),
            'group' => array('Award.name HAVING '.count($awards))
        )
    );
    

    【讨论】:

    • 我忘了说不能仅限于两个条件(本例中是两个奖项)。这是否意味着为了找到拥有 10 个不同奖项的人,我必须查询 Awards 10 次?
    • 我已经用另一种不会遇到以前问题的方式更新了我的答案。我认为从 SQL 的角度来看它甚至更快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多