我在处理查询时相对较新,所以让我提前道歉。
我的sql是
$sql1 = SELECT
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`, `user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_flown_international
FROM `event_contract`
LEFT JOIN `event` ON `event_id` = `event_contract_event_id`
LEFT JOIN `event_bid` ON `event_bid_event_id` = `event_id`
LEFT JOIN `user` ON `user_id` = `event_bid_td_id`
WHERE `event_bid_transportation_method` = 'airplane' AND event_location_country <> 'US'
$sql2 = SELECT
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`, `user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_flown_domestic
FROM `event_contract`
LEFT JOIN event ON event_id = event_contract_event_id
LEFT JOIN `event_bid` ON `event_bid_event_id` = `event_id`
LEFT JOIN `user` ON `user_id` = `event_bid_td_id`
WHERE `event_bid_transportation_method` = 'airplane' AND event_location_country = 'US' AND user_location_country = 'US'
$sql3 = SELECT
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`, `user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_driven
FROM `event_contract`
LEFT JOIN event ON event_id = event_contract_event_id
LEFT JOIN `event_bid` ON `event_bid_event_id` = `event_id`
LEFT JOIN `user` ON `user_id` = `event_bid_td_id`
WHERE `event_bid_transportation_method` IN ('auto', 'train')
仔细观察 from 部分和 left join 部分很常见,我想以一种方式组合
SELECT
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`, `user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_flown_international,
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`,
`user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_flown_domestic,
AVG( ST_Distance_Sphere( point( `event`.`event_location_longitude`, `event`.`event_location_latitude` ), point( `user`.`user_location_longitude`, `user`.`user_location_latitude` ) ) *.000621371192 ) as market_miles_driven
FROM `event_contract`
LEFT JOIN event ON event_id = event_contract_event_id
LEFT JOIN `event_bid` ON `event_bid_event_id` = `event_id`
LEFT JOIN `user` ON `user_id` = `event_bid_td_id`
WHERE where1 of $sql1, where2 of $sql2, where3 of $sql3
有什么办法吗?谢谢
您可以通过组合 WHERE 子句来做到这一点
建议
将所有 LEFT JOIN 子句更改为 INNER JOIN
最重要的问题是确保聚合在组合查询中返回与在单独查询中相同的结果。
您可以通过使聚合有条件地实现正确性,即通过将单独查询中使用的条件放在相应的调用中
AVG
。例如,如果您的第一个查询像这样聚合数据:那么组合查询应该像这样计算该值:
请注意
CASE
条件,并且条件WHEN
与第一个查询使用的条件完全相同。使用此条件,距离仅针对匹配条件的行进行聚合 - 与第一个查询相同,但现在查询正在处理也包含其他行的行集,因此您需要专门在聚集的时间。你所有的
AVG
电话都应该这样修改。就结果的准确性而言,是否还应在组合查询的子句中重复所有这些条件
WHERE
并不重要,尽管就性能而言它可能很重要。如果这些条件的总和大大过滤掉了基础集,那么重复它们WHERE
可能是有益的。如果您决定包含它们,请将它们与OR
:我还想提出另一个建议。您的组合查询必须
AVG
对每条数据进行三个单独的调用。这些调用中的每一个都将聚合相同的ST_Distance_Sphere
表达式,尽管是在不同的条件下。借助横向连接可以避免复杂表达式的重复,如下所示:这样,距离表达式将只定义一次。它将针对每一行进行计算,但有条件地进行聚合。