【发布时间】:2018-01-07 19:25:34
【问题描述】:
也许只是因为太晚了,这可能是超级简单的事情,但我的查询有问题:
$lead = Lead::findOrFail($id);
$recipients = Recipient::with('segment')
->select('recipients.*',
DB::raw('coalesce(rulesets.name, "Accept any...") as ruleset_name'),
DB::raw('coalesce(sum(recipient_leads.leads_left), 0) as leads_left'),
DB::raw('round(min('.((configuration('location_distance_unit') == 'km') ? '6371' : '3959').' * acos(cos(radians('.$lead->latitude.')) * cos(radians(recipient_locations.latitude)) * cos(radians(recipient_locations.longitude) - radians('.$lead->longitude.')) + sin(radians('.$lead->latitude.')) * sin(radians(recipient_locations.latitude))))) as distance'))
->leftJoin('rulesets', 'rulesets.id', '=', 'recipients.ruleset_id')
->leftJoin('recipient_leads', 'recipient_leads.recipient_id', '=', 'recipients.id')
->leftJoin('recipient_locations', 'recipient_locations.recipient_id', '=', 'recipients.id')
->where('recipients.segment_id', $lead->segment_id)
->where(function ($query) use ($lead) {
$query->whereIn('recipients.ruleset_id', $lead->rulesetIds())->orWhereNull('recipients.ruleset_id');
})
->whereRaw('distance <= recipient_locations.distance')
->where('recipients.active', true)
->where('leads_left', '>', 0)
->groupBy('recipients.id');
我的问题是 leads_left 的总和似乎乘以 recipient_locations 的数量。我尝试将recipient_locations.recipient_id 和recipient_leads.recipient_id 添加到我的groupBy,但没有效果。
为什么会发生这种情况,我该如何解决?
编辑:这是原始查询:
select
`recipients`.*,
coalesce(rulesets.name, "Accept any...") as ruleset_name,
coalesce(sum(recipient_leads.leads_left), 0) as leads_left,
round(min(6371 * acos(cos(radians(43.8988057)) * cos(radians(recipient_locations.latitude)) * cos(radians(recipient_locations.longitude) - radians(-78.6974833)) + sin(radians(43.8988057)) * sin(radians(recipient_locations.latitude))))) as distance
from `recipients`
left join `rulesets` on `rulesets`.`id` = `recipients`.`ruleset_id`
left join `recipient_leads` on `recipient_leads`.`recipient_id` = `recipients`.`id`
left join `recipient_locations` on `recipient_locations`.`recipient_id` = `recipients`.`id`
where `recipients`.`segment_id` = ? and (`recipients`.`ruleset_id` in (?, ?) or `recipients`.`ruleset_id` is null) and distance <= recipient_locations.distance and `recipients`.`active` = ? and `leads_left` > ?
group by `recipients`.`id`
【问题讨论】:
-
尝试使用 where
-
是多对多关系吗,可能是笛卡尔积
-
这是雄辩的?我讨厌查询构建器,它们丑陋且难以优化查询。
-
我需要使用haversine公式查询。我必须使用查询生成器。我只想知道为什么它不应该乘以leads_left的总和。
-
我已将实际的 SQL 查询添加到 OP。