Try using
DB::select('<your query here>');
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi all.
My goal is to retrieve nearest Providers model, located by longitude/latitude field contained in Towns table.
My tables are like:
Providers
`id` | `name` | `address_street` | `address_postal_code` | `address_town`
Towns ( where location is point field)
`id` | `name` | `postal_code` | `location`
The raw sql query is this:
SELECT `name`, `address_street`, `address_postal_code`, `address_town`
FROM (
SELECT `postal_code`
FROM `towns`
ORDER BY ST_DISTANCE(`towns`.`location`, (
SELECT `towns`.`location`
FROM `towns`
WHERE `towns`.`postal_code`= '83500'
LIMIT 1)
) ASC
LIMIT 5
) AS `nearby`
INNER JOIN `providers` ON `providers`.`address_postal_code` = `nearby`.`postal_code`
LIMIT 5
This query is working perfectly when submitted directly in database.
First I tried to use directly my raw query:
DB::query(DB::raw('
SELECT `name`, `address_street`, `address_postal_code`, `address_town`
FROM (
SELECT `postal_code`
FROM `towns`
ORDER BY ST_DISTANCE(`towns`.`location`, (
SELECT `towns`.`location`
FROM `towns`
WHERE `towns`.`postal_code`= '.$postal_code'
LIMIT 1)
) ASC
LIMIT 5
) AS `nearby`
INNER JOIN `providers` ON `providers`.`address_postal_code` = `nearby`.`postal_code`
LIMIT 5
'))->get();
But SELECT FROM SELECT seems to not work with DB::raw:
SQLSTATE[HY000]: General error: 1096 No tables used (SQL: select *)
Also it's not really eye-friendly in my Laravel app. So I want to use Laravel builder facade. But Hmm... That's not so easy...
I tried some few things, but I'm not able to get the same query, especially the inner join:
$visitor_town_query = Town::query();
$visitor_town = $visitor_town_query
->select(['location'])
->where('postal_code', $postal_code)
->take(1); // Some nearby-towns may have the same postal code
$five_nearest_towns_query = Town::query();
$five_nearest_towns = $five_nearest_towns_query
->select(['postal_code'])
->orderBY(DB::raw("ST_DISTANCE(`location`, (".$visitor_town->toSql()."))"), 'asc')
->take(5);
$five_nearest_providers_query = DB::query()
->select(['name', 'phone', 'address_town', 'address_street', 'address_postal_code'])
->fromRaw('('.$five_nearest_towns->toSql().')')
->take(5);
return $five_nearest_providers_query->toSql();
I'm using toSql() function on $five_nearest_towns just to see what I need to add in my query. Here is the SQL request generated:
select `name`, `phone`, `address_town`, `address_street`, `address_postal_code` from (select `postal_code` from `towns` order by ST_DISTANCE(`location`, (select `location` from `towns` where `postal_code` = ? limit 1)) asc limit 5) limit 5
Where to place inner join?? I feel like I ran in a dead end and maybe I choose wrong way?
Woaw... It was that simple...
It's still remain eye-unfriendly so if someone knows where to put my inner join...
[EDIT] I finally found solution, this is my final builder query:
$visitor_town_query = Town::query();
$visitor_town = $visitor_town_query
->select(['location'])
->where('postal_code', $postal_code)
->take(1);
$five_nearest_towns_query = Town::query();
$five_nearest_towns = $five_nearest_towns_query
->select(['postal_code'])
->orderBY(DB::raw("ST_DISTANCE(`location`, (".$visitor_town->toSql()."))"), 'asc')
->offset(10)
->limit(5);
$five_nearest_providers_query = DB::query()
->select(['name', 'phone', 'address_town', 'address_street', 'address_postal_code'])
->fromSub($five_nearest_towns, 'nearby')
->join('providers', 'providers.address_postal_code', '=', 'nearby.postal_code')
->distinct();
Please or to participate in this conversation.