วิธีนามแฝงตารางในแบบสอบถาม Laravel Eloquent (หรือใช้ตัวสร้างแบบสอบถาม)


147

สมมติว่าเราใช้ตัวสร้างแบบสอบถามของ Laravel:

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

ฉันกำลังมองหาเทียบเท่ากับ SQL นี้:

really_long_table_name AS short_name

สิ่งนี้จะเป็นประโยชน์อย่างยิ่งเมื่อฉันต้องพิมพ์ตัวเลือกและ wheres จำนวนมาก (หรือโดยทั่วไปแล้วฉันจะใส่ alias ในคอลัมน์ alias ของตัวเลือกเช่นกันและมันจะถูกใช้ในอาร์เรย์ผลลัพธ์) หากไม่มีนามแฝงของตารางจะมีการพิมพ์เพิ่มเติมสำหรับฉันและทุกอย่างกลายเป็นน้อยอ่านง่าย ไม่พบคำตอบในเอกสาร laravel ความคิดเห็นใด ๆ

คำตอบ:


218

Laravel ASสนับสนุนนามแฝงในตารางและคอลัมน์ที่มี ลอง

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

ลองดูด้วยtinkerเครื่องมือที่ยอดเยี่ยม

$ php ช่างฝีมือ
[1]> Schema :: create ('really_long_table_name', ฟังก์ชัน ($ table) {$ table-> การเพิ่มขึ้น ('id');});
// NULL
[2]> DB :: table ('really_long_table_name') -> insert (['id' => null]);
// จริง
[3]> DB :: table ('really_long_table_name AS t') -> select ('t.id AS uid') -> get ();
// array (
// 0 => วัตถุ (stdClass) (
// 'uid' => '1'
//)
//)

2
@ RubensMariuzzo ฉันรู้ ฉันเชื่อว่าคุณสามารถแสดงความคิดเห็นด้วยการร้องขอในฟอรั่มlaravel
peterm

2
@AldiUnanto แล้ว Eloquent ล่ะ? บันทึกที่ใช้งานหมายถึงการใช้ในตารางเดียวดังนั้นคุณไม่จำเป็นต้องใช้นามแฝง เมื่อคุณใช้ความสัมพันธ์คุณยังคงติดต่อกับตารางหนึ่งครั้ง (เช่นเมื่อคุณกำหนดตัวกรองในความสัมพันธ์) ตอนนี้ถ้าคุณกำลังใช้ตัวสร้างคิวรีกับโมเดล Eloquent (เช่นเข้าร่วม) คุณสามารถใช้นามแฝงในตารางที่เข้าร่วมทั้งหมด แต่ตารางโมเดล
เตอร์

1
@peterm จะเกิดอะไรขึ้นถ้าฉันใช้ตัวสร้างแบบสอบถามในแบบฝีปาก ฉันหมายถึงแบบจำลองฝีปากจำเป็นต้องประกาศคุณสมบัติที่มีการป้องกันสำหรับชื่อของตาราง (เช่นprotected $table = "books";) แล้วฉันจะสร้างชื่อแทนได้อย่างไร (เช่นสร้าง SQL: ... FROM books AS A ...)
Aldi Unanto

คุณสามารถทำได้protected $table = 'really_long_table_name AS short_name';แต่นั่นล้มเหลวใน INSERT นอกจากนี้ยังอาจทำลายแบบสอบถามความสัมพันธ์ ฉันใช้ Lumen และรูปแบบ DDD / Repository เพื่อหลีกเลี่ยง Eloquent อย่างสมบูรณ์
prograhammer

@peterm ฉันยังติดอยู่กับนามแฝง Eloquent คุณพบอะไรกับ Eloquent บ้างไหม?
Lizesh Shakya

77

วิธีใช้นามแฝงในโมเดลฝีปากแก้ไขโค้ดของคุณดังนี้:

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();

สิ่งนี้จะเพิ่มคำนำหน้าตารางไปยังชื่อตารางโดยอัตโนมัติและส่งคืนอินสแตนซ์ของItemsแบบจำลอง ไม่ใช่ผลการสืบค้นที่ไม่มีข้อมูล การเพิ่มDB::rawป้องกัน laravel จากการเพิ่มคำนำหน้าตารางไปยังนามแฝง


1
@ m3rg คุณเคยพบวิธีที่จะทำให้มันทำงานกับ soft delete หรือไม่? ข้อความค้นหาล้มเหลวโดยมีข้อผิดพลาดUnknown column 'table_alias.deleted_at'
dev7

สถานการณ์นี้เป็นอย่างไร SELECT * จาก fx_bank เป็นสิทธิ์อย่างถูกต้องเข้าร่วม fx_ex_keys เช่น b บน b.bank_id = a.id AND a.agent_type = 2 WHERE b.status = 1 และ b.group = -1;
GFxJamal

@jRhesk ใช้ DB :: raw ทุกที่เพื่อกำหนดชื่อแทนตารางเป้าหมาย วิธี Laravel อื่น ๆ จะใช้ตามปกติ
AMIB

@ m3rg @Yani ฉันใช้สิ่งนี้->withTrashed()และ->whereNull('table_alias.deleted_at')
Firman Hidayat

8

นี่คือวิธีหนึ่งสามารถทำได้ ฉันจะให้ตัวอย่างกับการเข้าร่วมเพื่อที่จะกลายเป็นชัดเจนกับใครบางคน

$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();

หวังว่านี่จะช่วยได้


คุณสามารถให้ตัวอย่างที่นามแฝงมีช่องว่างแทนการขีดล่าง (_) ได้หรือไม่?
Channox

7

เพื่อใช้ในภาษาฝีปาก เพิ่มที่ด้านบนของแบบจำลองของคุณ

protected $table = 'table_name as alias'

// table_name ควรตรงตามฐานข้อมูลของคุณ

.. จากนั้นใช้ในแบบสอบถามของคุณเช่น

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


1
Laravel มีคารมคมคายการออกแบบที่ดีมากนามแฝงที่คุณกำหนดไว้ด้านบนปรับสำหรับแบบสอบถามการดำเนินการ แต่การปรับปรุงและลบจะเกิดข้อผิดพลาดเพราะนามแฝงของคุณ
มาตรการ

1

คุณสามารถใช้รหัสน้อยลงเขียนสิ่งนี้:

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

และแน่นอนถ้าคุณต้องการเลือกเขตข้อมูลเพิ่มเติมเพียงแค่เขียน "," และเพิ่ม:

 $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'));

สิ่งนี้มีประโยชน์มากเมื่อคุณใช้การสืบค้นที่ซับซ้อน


0

เช่นเดียวกับคำตอบ AMIB สำหรับข้อผิดพลาดการลบแบบอ่อน "คอลัมน์ที่ไม่รู้จัก 'table_alias.deleted_at'" เพียงเพิ่ม->withTrashed()แล้วจัดการด้วยตัวเองเช่น->whereRaw('items_alias.deleted_at IS NULL')

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.