3

i have a table call bank, which store the country bank name, code, etc

i have a table call site_banks, which store the bank account, bank holder name and foreign bank_id which refer to bank

i have a table call deposit_records, which store deposit time, deposit receipt, status, etc and foreign bank_id which refer to site_banks

for deposit_records, the status field, value 1 mean successfully

now i want to calculate the total income for each site_banks

but i don't want each row site_banks call one query to count, this will have a lots of sql query call

so i think i can use the join, below is the site_banks model file, the scopeGroupAllSiteBanksByBranch is where i want to collect all site_banks, join with SUM, return in array

but even i have about 200 site_banks rows, a lots of deposit_records rows which is status = '1', but the scopeGroupAllSiteBanksByBranch will always return only one row, i don't understand why, i copy the sql query to run in mysql, is same result, only 1 row return.

<?php

use Illuminate\Database\Eloquent\SoftDeletingTrait;

class SiteBanks extends \LaravelBook\Ardent\Ardent {

    use SoftDeletingTrait;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'site_banks';

    protected $dates = ['deleted_at'];

    protected $fillable = array('bank_id', 'bank_name', 'bank_account', 'bank_holder', 'bank_username', 'bank_password', 'min_deposit', 'max_deposit', 'daily_max_deposit');

    public static $rules = array(
        'bank_id' => 'required|exists:banks,id',
        'bank_name' => 'required|min:1',
        'bank_account' => 'required|min:1|numberonly',
        'bank_holder' => 'required|min:1',
        'bank_username' => 'required|min:1',
        'bank_password' => 'required|min:1',
        'min_deposit' => 'required|fund',
        'max_deposit' => 'required|fund',
        'daily_max_deposit' => 'required|fund',
    );

    public function bank() {
        return $this->belongsTo('Banks', 'bank_id');
    }

    public function transactions() {
        return $this->hasMany('Deposit', 'bank_id', 'id');
    }

    public function transactionsDone() {
        return $this->hasMany('Deposit', 'bank_id', 'id')->where('status', '=', 1);
    }

    public function transactionsBanned() {
        return $this->hasMany('Deposit', 'bank_id', 'id')->where('status', '=', 2);
    }

    public function transactionsPending() {
        return $this->hasMany('Deposit', 'bank_id', 'id')->where('status', '=', 0);
    }

    public function setBankPasswordAttribute($value) {
        $this->attributes['bank_password'] = Crypt::encrypt($value);
    }

    public function getBankPasswordAttribute() {
        return Crypt::decrypt($this->attributes['bank_password']);
    }

    public function scopeGetAvailableBanks($query) {
        $query->where(DB::raw("(current_deposit < daily_max_deposit) OR (current_deposit IS NULL) OR (DATE(last_deposit) != DATE(NOW()) OR last_deposit IS NULL) OR (DATE(last_deposit) = DATE(NOW()) && current_deposit < daily_max_deposit)"));
        $query->groupBy('bank_id')->orderBy('id', 'ASC');
    }

    public function scopeGroupAllSiteBanksByBranch($query) {
        $bank = \SiteBanks::withTrashed()
            ->leftJoin('deposit_records', function($q) {
                $q->on('deposit_records.bank_id', '=', 'site_banks.id');
                $q->where('deposit_records.status', '=', 1, 'and');
            })
            ->select(array('site_banks.*', DB::raw('SUM(`deposit_records`.`deposit_amount`) AS `total_income`')))
            ->get();
//        $bank = \SiteBanks::withTrashed()->get();
        $bank->load('bank');

        $banks = array();
        foreach($bank as $key => $var) {
            $arr = array();

            $arr = $var->toArray();
            $arr['income'] = $var->total_income;
            $banks[$var->bank->bank_name][] = $arr;
        }

        return $banks;
    }

}

SQL Query

select site_banks.*, SUM(deposit_records.deposit_amount) AS total_income from site_banks left join deposit_records on deposit_records.bank_id = site_banks.id and deposit_records.status = '1'

var_dump the result from scopeGroupAllBanksByBranch

array (size=1)
  'BANKNAME' => 
    array (size=1)
      0 => 
        array (size=20)
          'id' => int 1
          'bank_id' => int 4
          'bank_name' => string 'BANKNAME' (length=6)
          'bank_account' => string '123456789' (length=9)
          'bank_holder' => string 'ACCOUNT HOLDER NAME' (length=11)
          'bank_username' => string 'username' (length=8)
          'bank_password' => string 'hehethisispassword' (length=18)
          'min_deposit' => string '400.00' (length=6)
          'max_deposit' => string '9999.99' (length=7)
          'daily_max_deposit' => string '25500.00' (length=8)
          'last_deposit' => string '2015-02-05 03:04:00' (length=19)
          'current_deposit' => string '0.00' (length=4)
          'created_by' => int 1
          'updated_by' => null
          'created_at' => string '2015-02-04 08:21:16' (length=19)
          'updated_at' => string '2015-02-04 08:21:16' (length=19)
          'deleted_at' => null
          'total_income' => string '1722.00' (length=7)
          'bank' => 
            array (size=7)
              ...
          'income' => string '1722.00' (length=7)

3 Answers 3

8

You can solved your problem by following the code

SQL query

LEFT JOIN bookings  
           ON rooms.id = bookings.room_type_id AND (bookings.arrival = ? OR bookings.departure = ? )

Laravel join with multiple condition

 ->join('bookings', function($join) use ($key1, $key2)
{
    $join->on('rooms.id', '=', 'bookings.room_type_id');
    $join->on(function($query) use ($key1, $key2)
            {
             $query->on('bookings.arrival', '=', $key1);
             $query->orOn('departure', '=',$key2);
            });

})
Sign up to request clarification or add additional context in comments.

Comments

3
public function scopeGroupAllSiteBanksByBranch($query) {
        $bank = \SiteBanks::withTrashed()
            ->leftJoin('deposit_records', function($q) {
                $q->on('deposit_records.bank_id', '=', 'site_banks.id');
                $q->where('deposit_records.status', '=', 1, 'and');
            })
            ->select(array('site_banks.*', DB::raw('SUM(`deposit_records`.`deposit_amount`) AS `total_income`')))
            ->groupBy('site_banks.id')
            ->get();

i found the solutions, with groupBy('site_banks.id') then is all set.

Comments

1

Here is The Solution. you can join with multiple conditions.

$query = self::select('websites.id','websites.website_url','cron_tracking_details.cron_type');
    $query = $query->leftJoin('cron_tracking_details',function ($join){
        $join->on(function ($queryone){
            $queryone->on('websites.id','=','cron_tracking_details.website_id');
            $queryone->where('cron_tracking_details.cron_type','=',"sitemap_create");
            $queryone->Where('cron_tracking_details.cron_date','<','2020-11-19');
        });
    });
    $query = $query->orderBy('cron_tracking_details.id','desc');
    $query = $query->limit(1);
    return $query = $query->get();

This code will prepare Query like this.

select `websites`.`id`, `websites`.`website_url`, `cron_tracking_details`.`cron_type` from `websites` left join `cron_tracking_details` on (`websites`.`id` = `cron_tracking_details`.`website_id` and `cron_tracking_details`.`cron_type` = ? and `cron_tracking_details`.`cron_date` < ?) order by `cron_tracking_details`.`id` desc limit 1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.