Optimumkan Laravel Join untuk mendapatkan semula semua data dalam satu baris tanpa menduplikasi jadual
P粉410239819
P粉410239819 2024-01-16 11:40:46
0
1
461

Saya mempunyai 4 jadual MySQL, menggunakan PHP dan Laravel 7

  1. Ahli
  2. Potongan
  3. Bayaran
  4. Potongan Bayaran

Sekarang saya ingin memaparkan bayaran tunggal setiap ahli dan semua potongan lain secara berterusan. (Andaikan seorang hanya mempunyai satu bayaran)

Struktur pangkalan data adalah seperti berikut

Ini adalah jadual HTML yang saya ingin paparkan

Ini adalah pertanyaan yang saya gunakan, tetapi ia menduplikasi data.

$payments = Payment::leftJoin('members', 'payments.member_id', '=', 'members.id')
        ->leftJoin('payment_deductions', 'payments.id', '=', 'payment_deductions.payment_id')
        ->leftJoin('deductions', 'payment_deductions.deduction_id', '=', 'deductions.id')
        ->select(
            'members.*',
            'payment_deductions.*',
        )
        ->orderBy("member_id", "ASC")
        ->get()->toArray();

Tatasusunan yang terhasil mengulangi setiap ahli berdasarkan terbitannya.

Adakah terdapat cara untuk mendapatkan data ini dengan lebih baik? Sesuatu seperti susunan potongan bersarang untuk setiap ahli?

Inilah modelnya

Ahli

namespace App;

    use IlluminateDatabaseEloquentModel;
    use CarbonCarbon;

    class Member extends Model
    {
        protected $fillable = [
            'full_name',
            'email',
            'created_by',
        ];
    }

Bayaran

namespace App;

    use IlluminateDatabaseEloquentModel;

    class Payment extends Model
    {
        protected $fillable = [
            'member_id',
            'total_amount',
            'payable_amount',
            'created_by',
        ];

        public function deductions() {
           return $this->belongsToMany(Deduction::class,'payment_deductions')->withTimestamps();
        }
    }

Potongan

namespace App;

    use IlluminateDatabaseEloquentModel;

    class Deduction extends Model
    {
        protected $fillable = [
        'title',
        'priority',
        'created_by',
        ];
    }


P粉410239819
P粉410239819

membalas semua(1)
P粉239089443

Anda sangat rapat dan berada di landasan yang betul semasa membina model, apa yang anda hilang ialah cara memuatkan perhubungan tanpa membuat pertanyaan lain, jika anda melihat pengawal anda akan melihat cara standard memuatkan perhubungan di dalamnya. Semoga ini adalah konsep yang lebih baik untuk menangani kebimbangan anda.

Untuk rujukan: https://laravel.com/docs/9.x/eloquent-relationships#lazy-eager-loading

Melakukan ini juga akan mengelakkan masalah N+1 akan datang, lihat Apakah "masalah pemilihan N+1" dalam ORM (Pemetaan Hubungan Objek)? N+1 问题,请参阅什么是 ORM(对象关系映射)中的“N+1 选择问题”? 有关 N+1 Butiran tentang N+1

Model Ahli

public class Member extends Model
{
    protected $fillable = [
       'full_name',
       'email',
       'created_by',
    ];
        
    public function payments(){
        return $this->hasMany(Payment::class);
    }
}

Mod Pembayaran

public class Payment extends Model
{
    protected $fillable = [
       'member_id',
       'total_amount',
       'payable_amount',
       'created_by',
    ];
        
    public function member(){
        return $this->belongsTo(Member::class);
    }

    public function deductions() {
        return $this->belongsToMany(Deduction::class,'payment_deductions')->withTimestamps();
    }
}

Model potongan

public class Deduction extends Model
{
    protected $fillable = [
       'title',
       'priority',
       'created_by',
    ];
        
    public function payments() {
        return $this->belongsToMany(Payment::class,'payment_deductions')->withTimestamps();
    }
}

Pengawal Ahli:

/**
 * Show the specified model.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  Member $member
 * @return \Illuminate\Http\Response
 */
public function show(Request $request, Member $member){
    // This will load all of the inner relationships in a single query.
    $member->load('payments.deductions');
        
    //Assign the loaded payments to be used
    $payments = $member->payments;
        
    /* 
        You can acess the payments -> deductions in a foreach loop, in php or blade
        foreach($payments->deductions as $deduction){
           //$deduction->id   
        }
    */  
        
    return view('sampleView', compact('member', 'payments'));
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!