在我正在构建的雄辩查询中,我使用Laravel 4.1的has
和whereHas
方法对orWhereHas
关系施加约束。
在示例足球应用程序中,我希望对homeClub
和awayClub
关系设置约束,以便我可以在结果集中选择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'
注意俱乐部子查询中的括号。
有谁知道我会如何写这个作为雄辩的查询?我真的不想恢复流利/加入。
答案 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();