Skip to content

[5.6] Adding fromSub and fromRaw methods to query Builder - #23476

Merged
taylorotwell merged 2 commits into
laravel:5.6from
henriquepedrosa:fromsub
Mar 12, 2018
Merged

[5.6] Adding fromSub and fromRaw methods to query Builder#23476
taylorotwell merged 2 commits into
laravel:5.6from
henriquepedrosa:fromsub

Conversation

@henriquepedrosa

@henriquepedrosa henriquepedrosa commented Mar 10, 2018

Copy link
Copy Markdown
Contributor

Added

  • fromSub and fromRaw methods to Query Builder so the user can create a subquery on "from", instead of only being able to use table names.

Example

$builder->fromSub(function ($query) {
    $query->select(new Raw('max(last_seen_at) as last_seen_at'))->from('user_sessions')->where('foo', '=', '1');
}, 'sessions')->where('bar', '<', '10');

This creates the following sql:

select * from (select max(last_seen_at) as last_seen_at from "user_sessions" where "foo" = ?) as "sessions" where "bar" < ?

@henriquepedrosa henriquepedrosa changed the title Adding fromSub and fromRaw methods to query Builder [5.6] Adding fromSub and fromRaw methods to query Builder Mar 10, 2018
@taylorotwell
taylorotwell merged commit b13d5e0 into laravel:5.6 Mar 12, 2018
@taist24

taist24 commented Jul 28, 2021

Copy link
Copy Markdown

How to add an alias to the derived table when using fromRaw()?

1.) Union Query

$postLikes = DB::table($table, 'n')
    ->select('n.*', 'reference_id AS post_id', DB::raw('NULL AS comment'))
    ->where('type', AppNotification::LIKE_POST_NOTIFICATION);

$postComments = DB::table($table, 'n')
    ->select('n.*', 'pc.post_id', 'pc.comment')
    ->join('post_comments AS pc', 'n.reference_id', '=', 'pc.id')
    ->where('type', AppNotification::COMMENT_ON_POST_NOTIFICATION);

$postCommentReplies = DB::table($table, 'n')
    ->select('n.*', 'pc.post_id', 'pcr.reply')
    ->join('post_comment_replies AS pcr', 'n.reference_id', '=', 'pcr.id')
    ->join('post_comments AS pc', 'pcr.post_comment_id', '=', 'pc.id')
    ->where('type', AppNotification::REPLY_ON_POST_NOTIFICATION);

$unionOfAllTables = $postLikes->union($postComments)->union($postCommentReplies);

Output

# Outputs:
----------
(select `n`.*, `reference_id` as `post_id`, NULL AS comment from `app_notifications` as `n` where `type` = ?)
union
(select `n`.*, `pc`.`post_id`, `pc`.`comment` from `app_notifications` as `n` inner join `post_comments` as `pc` on `n`.`reference_id` = `pc`.`id` where `type` = ?)
union
(select `n`.*, `pc`.`post_id`, `pcr`.`reply` from `app_notifications` as `n` inner join `post_comment_replies` as `pcr` on `n`.`reference_id` = `pcr`.`id` inner join `post_comments` as `pc` on `pcr`.`post_comment_id` = `pc`.`id` where `type` = ?)

2. Using fromRaw() with the above union query

$data = DB::query()->fromRaw("({$unionOfAllTables->toSql()})", $unionOfAllTables->getBindings())->get();

Output

select * from (
  (select `n`.*, `reference_id` as `post_id`, NULL AS comment from `app_notifications` as `n` where `type` = ?)
  union
  (select `n`.*, `pc`.`post_id`, `pc`.`comment` from `app_notifications` as `n` inner join `post_comments` as `pc` on `n`.`reference_id` = `pc`.`id` where `type` = ?)
  union
  (select `n`.*, `pc`.`post_id`, `pcr`.`reply` from `app_notifications` as `n` inner join `post_comment_replies` as `pcr` on `n`.`reference_id` = `pcr`.`id` inner join `post_comments` as `pc` on `pcr`.`post_comment_id` = `pc`.`id` where `type` = ?)
) // <--- Notice the error here as it's missing the alias for the derived table

@walidbagh

Copy link
Copy Markdown

both those methods are not documented ...

@vserdobintsev

Copy link
Copy Markdown

Please add to documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants