I think the trick to achieve the query you are trying to write with eloquent is making the subquery with the union the joinSub() part of it.
I made this using laravel's User model. First, build the two subqueries for the union inside.
$query1 = User::query()
->selectRaw('min(id) as "info"')
->selectRaw("'min' as \"infoType\"");
$query2 = User::query()
->selectRaw('max(id) as "info"')
->selectRaw("'max' as \"infoType\"")
->union($query1);
I'm using postgres, so you might have to tweak the field delimiters if you're using mysql
If I run $query2 this is the sql generated:
(
select
max(id) as "info",
'max' as "infoType"
from
"users"
)
union
(
select
min(id) as "info",
'min' as "infoType"
from
"users"
)
which returns two rows.
Then you assemble everything with the main model
$rows = User::query()
->select(['id', 'name', 'join_sub.infoType', 'join_sub.info'])
->joinSub($query2, 'join_sub', 'users.id', '=', 'join_sub.info')
->get()
;
And all of that makes:
select
"id",
"name",
"join_sub"."infoType",
"join_sub"."info"
from
"users"
inner join (
(
select
max(id) as "info",
'max' as "infoType"
from
"users"
)
union
(
select
min(id) as "info",
'min' as "infoType"
from
"users"
)
) as "join_sub" on "users"."id" = "join_sub"."info"