orWhereHas - Eloquent查询的参数分组 - 如何在Laravel中执行此操作?

时间:2014-01-27 14:03:40

标签: laravel-4

在我正在构建的雄辩查询中,我使用Laravel 4.1的haswhereHas方法对orWhereHas关系施加约束。

在示例足球应用程序中,我希望对homeClubawayClub关系设置约束,以便我可以在结果集中选择homeClub = Arsenal OR awayClub = Arsenal。

此问题已从earlier question演变而来似乎在使用orWhereHas方法时 - 生成的sql不会对or约束进行分组。

查询(放置约束的相关摘录):

$ret
        ->where( function( $subquery ) use ( $ret ){
            $ret->whereHas('homeClub', function ( $query ){
                $query->where('name','Arsenal' );
            })->orWhereHas('awayClub',function ( $query ){
                $query->where('name','Arsenal' );
            });
        })
        ->where( function ( $subquery ) use ( $ret, $parameterValues ){
            $ret->whereHas('season', function ($query) use ( $parameterValues ){
                $query->where('name', $parameterValues['season_names'] );

            });
        } )
        ->whereHas('territory',function( $query ) use ( $parameterValues ){     
               $query->where('region','Australia');

        })->get()->toArray();

这会生成sql:

SELECT * FROM `broadcasts` WHERE 

(SELECT count(*) FROM `uploads` WHERE `broadcasts`.`upload_id` = `uploads`.`id` and `type` = 'international-audience') >= '1' 
and 
(SELECT count(*) FROM `clubs` WHERE `clubs`.`id` = `broadcasts`.`home_club_id` and `name` = 'Arsenal') >= '1' 
or 
(SELECT count(*) FROM `clubs` WHERE `clubs`.`id` = `broadcasts`.`away_club_id` and `name` = 'Arsenal') >= '1' 
and 
(SELECT count(*) FROM `seasons` WHERE `broadcasts`.`season_id` = `seasons`.`id` and `name` = '2012/13') >= '1' 
and 
(SELECT count(*) FROM `territories` WHERE `broadcasts`.`territory_id` = `territories`.`id` and `region` = 'Australia') >= '1'

但是,这不是我想要的,因为参考雄辩的陈述,俱乐部的查询是grouped,上面的查询要么选择homeClub约束OR,要么选择客场俱乐部,赛季名称,领域区域。我想要的是以下SQL:

SELECT * FROM `broadcasts` WHERE 

(SELECT count(*) FROM `uploads` WHERE `broadcasts`.`upload_id` = `uploads`.`id` and `type` = 'international-audience') >= '1' 
and 
((SELECT count(*) FROM `clubs` WHERE `clubs`.`id` = `broadcasts`.`home_club_id` and `name` = 'Arsenal') >= '1' 
or 
(SELECT count(*) FROM `clubs` WHERE `clubs`.`id` = `broadcasts`.`away_club_id` and `name` = 'Arsenal') >= '1' )
and 
(SELECT count(*) FROM `seasons` WHERE `broadcasts`.`season_id` = `seasons`.`id` and `name` = '2012/13') >= '1' 
and 
(SELECT count(*) FROM `territories` WHERE `broadcasts`.`territory_id` = `territories`.`id` and `region` = 'Australia') >= '1'

注意俱乐部子查询中的括号。

有谁知道我会如何写这个作为雄辩的查询?我真的不想恢复流利/加入。

1 个答案:

答案 0 :(得分:15)

您需要引用传递给where闭包的查询。否则,您将绕过任何分组将分组的where子句添加到主查询中:

$ret
->where( function( $query ){
    $query->whereHas('homeClub', function ( $subquery ){
        $subquery->where('name','Arsenal' );
    })
    ->orWhereHas('awayClub',function ( $subquery ){
        $subquery->where('name','Arsenal' );
    });
})
->where( function ( $query ) use ( $parameterValues ){
    $query->whereHas('season', function ($subquery) use ( $parameterValues ){
        $subquery->where('name', $parameterValues['season_names'] );
    });
})
->whereHas('territory',function( $query ) use ( $parameterValues ){     
    $query->where('region','Australia');
})
->get();