ChatGPT解决这个技术问题 Extra ChatGPT

How to alias a table in Laravel Eloquent queries (or using Query Builder)?

Lets say we are using Laravel's query builder:

$users = DB::table('really_long_table_name')
           ->select('really_long_table_name.id')
           ->get();

I'm looking for an equivalent to this SQL:

really_long_table_name AS short_name

This would be especially helpful when I have to type a lot of selects and wheres (or typically I include the alias in the column alias of the select as well, and it gets used in the result array). Without any table aliases there is a lot more typing for me and everything becomes a lot less readable. Can't find the answer in the laravel docs, any ideas?


p
peterm

Laravel supports aliases on tables and columns with AS. Try

$users = DB::table('really_long_table_name AS t')
           ->select('t.id AS uid')
           ->get();

Let's see it in action with an awesome tinker tool

$ php artisan tinker
[1] > Schema::create('really_long_table_name', function($table) {$table->increments('id');});
// NULL
[2] > DB::table('really_long_table_name')->insert(['id' => null]);
// true
[3] > DB::table('really_long_table_name AS t')->select('t.id AS uid')->get();
// array(
//   0 => object(stdClass)(
//     'uid' => '1'
//   )
// )

@RubensMariuzzo I know. I believe you can leave a comment with request in laravel forums forums.laravel.io
@AldiUnanto What about Eloquent? Active record meant to be used on one table therefore you don't need aliases. When you use relations you're still dealing with one table at a time (i.e. when you define filters on the relationship). Now if you're using Query Builder with an Eloquent model (i.e. join) then you can use aliases on all joined tables, but the model table.
@peterm what if I use query builder in eloquent? I mean eloquent model need to declare a protected property for table's name (e.g. protected $table = "books";) then how can I make an aliases? (e.g. generated sql: ... FROM books AS A ...)
You could do protected $table = 'really_long_table_name AS short_name'; but that'd fail on INSERTs though. Also may break relationship queries. I'm using Lumen and a DDD/Repository pattern to avoid Eloquent completely.
@peterm I am also stuck with Eloquent alias. Did u find anything with Eloquent?
A
AMIB

To use aliases on eloquent models modify your code like this:

Item
    ::from( 'items as items_alias' )
    ->join( 'attachments as att', DB::raw( 'att.item_id' ), '=', DB::raw( 'items_alias.id' ) )
    ->select( DB::raw( 'items_alias.*' ) )
    ->get();

This will automatically add table prefix to table names and returns an instance of Items model. not a bare query result. Adding DB::raw prevents laravel from adding table prefixes to aliases.


@m3rg have you ever found a way to make it work with soft delete? query fails with error Unknown column 'table_alias.deleted_at'
how about this situation? SELECT * FROM fx_bank AS a RIGHT OUTER JOIN fx_ex_keys AS b on b.bank_id=a.id AND a.agent_type=2 WHERE b.status=1 AND b.group=-1;
@jRhesk Use DB::raw everywhere to target table aliases. other Laravel methods are used as normal
@m3rg @Yani i use this ->withTrashed() and ->whereNull('table_alias.deleted_at')
No need for DB::raw in the join call
K
Koushik Das

Here is how one can do it. I will give an example with joining so that it becomes super clear to someone.

$products = DB::table('products AS pr')
        ->leftJoin('product_families AS pf', 'pf.id', '=', 'pr.product_family_id')
        ->select('pr.id as id', 'pf.name as product_family_name', 'pf.id as product_family_id')
        ->orderBy('pr.id', 'desc')
        ->get();

Hope this helps.


Can you provide an example wherein alias has whitespace instead of underscore(_) ?
m
muinh

To use in Eloquent. Add on top of your model

protected $table = 'table_name as alias'

//table_name should be exact as in your database

..then use in your query like

ModelName::query()->select(alias.id, alias.name)


Laravel eloquent very poor design, alias you define above fine for operation query, but update and delete will error because your alias.
C
Carlos h Gonzalez

You can use less code, writing this:

    $users = DB::table('really_long_table_name')
       ->get(array('really_long_table_name.field_very_long_name as short_name'));

And of course if you want to select more fields, just write a "," and add more:

 $users = DB::table('really_long_table_name')
       ->get(array('really_long_table_name.field_very_long_name as short_name', 'really_long_table_name.another_field as other', 'and_another'));

This is very practical when you use a joins complex query


J
JW Geertsma

I have tried all these options and none works for me. Then I had found something in the Laravel documentation that really works.

You could try this:

DB::table('table_one as t1')
    ->select(
        't1.field_id as id','t2.field_on_t2 as field'
     )->join('table_two as t2', function ($join) {
        $join->on('t1.field_id ', '=', 't2.field_id');
    })->get()

t
theDude

Also note that you can pass an alias as the second parameter of the table method when using the DB facade:

$users = DB::table('really_long_table_name', 'short_name')
           ->select('short_name.id')
           ->get();

Not sure if this feature came with a specific version of Laravel or if it has always been baked in.


A
Ahmed Gamal

Same as AMIB answer, for soft delete error "Unknown column 'table_alias.deleted_at'", just add ->withTrashed() then handle it yourself like ->whereRaw('items_alias.deleted_at IS NULL')