I would like to convert this following Postgre SQL query in an Eloquent query:
SELECT ncts_info.nct_id, A.agency_model, ncts_info.indexation_id
FROM ncts_info
LEFT JOIN (
drug_centers LEFT JOIN LATERAL json_to_recordset(nct_numbers) AS tbl(nct_number text) ON true
) A ON A.nct_number = ncts_info.nct_id
How can I convert this into an Eloquent query?
I managed somehow to partially get the right Laravel query but something is missing:
NctsInfo::leftJoin('drug_centers', function($join) {
$join->leftJoin(DB::raw('LATERAL json_to_recordset(nct_numbers) AS tbl(nct_number text)'), DB::raw('1'), '=', DB::raw('1'));
$join->on(DB::raw('dc.nct_number'), '=' ,DB::raw('ncts_info.nct_id'));
})
->whereNotNull("nct_numbers")->get();
But according to my expected sql query:
SELECT ncts_info.nct_id, A.agency_model, ncts_info.indexation_id FROM ncts_info
LEFT JOIN (
drug_centers LEFT JOIN LATERAL json_to_recordset(nct_numbers) AS tbl(nct_number text) ON true
) A ON A.nct_number = ncts_info.nct_id
I need to "alias" my first left join with "A" to get my nct_number field.
Anyone knows how to solved this?
Thank you for your help
The best way I've found to do this is to define a subquery first. From the laravel docs:
Posts = DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
->where('is_published', true)
->groupBy('user_id');
$users = DB::table('users')
->joinLeftSub($latestPosts, 'latest_posts', function ($join) {
$join->on('users.id', '=', 'latest_posts.user_id');
})->get();
In your second response here, you mention that you need to reference the join as A
- you don't need to. You can change A
to drug_centers
in Laravel as it will be aliased as the table name.
FWIW, I solved the original question by creating a custom Macro for the Builder class that will let you do a join prefixed with the LATERAL keyword:
Builder::macro('joinSubLateral', function ($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false) {
[$query, $bindings] = $this->createSub($query);
$expression = 'LATERAL ('.$query.') as '.$this->grammar->wrapTable($as);
$this->addBinding($bindings, 'join');
return $this->join(new Expression($expression), $first, $operator, $second, $type, $where);
});
Put this in the register
method of a Service Provider and you're all set!
Keep in mind it doesn't check for database compatibility.
You can use DB like that in laravel
$data = DB::table('ncts_info')
->leftJoin('drug_centers', 'drug_centers.foreign_key', 'ncts_info.id')
->select('ncts_info.nct_id','A.agency_model','ncts_info.indexation_id')
->get();
This would produce the following query:
SELECT "ncts_info"."nct_id", "A"."agency_model", "ncts_info"."indexation_id"
FROM "ncts_info"
LEFT JOIN "drug_centers" ON "drug_centers"."foreign_key" = "ncts_info"."id";
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.