php - Laravel 查询生成器 - 在 WHERE 子句中使用选定的值而不重复代码
问题描述
我正在尝试将 RAW SQL 查询转换为 Laravel 查询生成器,但是我不知道如何在 WHERE 子句的选择语句中使用派生值。在 RAW SQL 中执行此操作时,我通过嵌套选择查询来执行此操作。
工作 RAW 查询
$query = DB::select("
SELECT *
FROM
(SELECT DISTINCT a.postcode, b.id, b.name, d.product, e.distance product_distance,
ROUND((SELECT 6371 * acos( cos( radians( $lat ) ) * cos( radians( a.latitude ) )
* cos( radians( $lng ) - radians(a.longitude) )
+ sin( radians( $lat ) ) * sin( radians( a.latitude ) ) ) ),0) AS point_distance
FROM postcodes_geo AS a
JOIN businesses As b
ON b.postcode = a.postcode
JOIN business_services As c
ON b.id = c.business_id
JOIN business_subscriptions As d
ON b.id = d.business_id
JOIN ref_business_products AS e
ON d.product = e.product
WHERE b.deleted_at IS NULL
AND c.service = '$service'
AND c.deleted_at IS NULL) t
WHERE t.point_distance <= t.product_distance
ORDER BY point_distance
");
当前查询生成器查询
$query = DB::table('postcodes_geo')
->join('businesses', 'postcodes_geo.postcode', '=', 'businesses.postcode')
->join('business_services', 'businesses.id', '=', 'business_services.business_id')
->join('business_subscriptions', 'businesses.id', '=', 'business_subscriptions.business_id')
->join('ref_business_products', 'business_subscriptions.product', '=', 'ref_business_products.product')
->select(DB::raw("DISTINCT postcodes_geo.postcode, businesses.id, businesses.name, business_subscriptions.product, ref_business_products.distance,
ROUND((SELECT 6371 * acos( cos( radians( $lat ) ) * cos( radians( postcodes_geo.latitude ) )
* cos( radians( $lng ) - radians(postcodes_geo.longitude) )
+ sin( radians( $lat ) ) * sin( radians( postcodes_geo.latitude ) ) ) ),0) AS point_distance"))
->whereNull('businesses.deleted_at')
->whereNull('business_services.deleted_at')
->when($services, function ($query, $services) {
return $query->whereIn('business_services.service', explode(',', $services));
})
->where(DB::raw("ROUND((SELECT 6371 * acos( cos( radians( $lat ) ) * cos( radians( postcodes_geo.latitude ) )
* cos( radians( $lng ) - radians(postcodes_geo.longitude) )
+ sin( radians( $lat ) ) * sin( radians( postcodes_geo.latitude ) ) ) ),0)"), "<=", 'ref_business_products.distance')
->get();
解决方案
您可以利用 MySQL 的重载HAVING
子句,这将允许您引用point_distance
select 子句中定义的别名:
$query = DB::table('postcodes_geo')
...
->having(DB::raw('point_distance <= ref_business_products.distance'))
->get();
注意:如果您使用的是早于 5.7.5 的 MySQL 版本,那么您需要关闭ONLY_FULL_GROUP_BY
模式以使用重载HAVING
,正如我在回答中所做的那样。
推荐阅读
- ios - 如何限制 Firebase 上的星数?
- c# - C#检查变量是否不同并设置或只是设置
- c# - 如何使用 jquery ASP.NET 在 MVC 中应用搜索过滤器
- c# - SQLite 错误:尝试写入只读数据库
- javascript - 通过数组检查多个值,应该返回一个值
- permissions - 父/子权限分组
- django - uwsgi with Emperor/systemd:宣布忠诚度最多需要 3 分钟
- java - 无法解析方法 getYouTubeService()
- java - 每次使用 android studio 按下按钮时,如何让 1 个按钮播放随机声音
- python - 无法为形状为 '(?, 2048)' 的张量 u'input_ph:0' 提供形状 (480, 720, 3) 的值