在Laravel查询构建器中的with()内使用leftJoin()

时间:2018-08-23 04:24:15

标签: php laravel eloquent left-join

我正在使用会计软件。我有3张桌子

chart_master:包含所有帐户

chart_types:包含帐户类型

bank_accounts:包含银行帐户(这些银行帐户也位于chart_master

我要转换以下SQL查询,该查询选择accounts中的所有chart_master以及将account_typeschart_master连接起来的chart_types,然后排除检索到的记录中bank_accounts中的记录到laravel查询构建器中。查询:

SELECT chart.account_code, chart.account_name, type.name, chart.inactive, type.id
        FROM (chart_master chart, chart_types type) "
        ."LEFT JOIN bank_accounts acc "
        ."ON chart.account_code=acc.account_code
            WHERE acc.account_code  IS NULL
        AND chart.account_type=type.id

我可以使用以下内容选择accounts,而排除bank_accounts

    \App\Account::leftJoin('bank_accounts', 'chart_master.account_code', '=', 'bank_accounts.account_code')
->whereNull('bank_accounts.account_code')->get()

但这并没有实现我想要的同时检索chart_masterchar_types之间的关系的目的。我认为可以通过以下方式实现

 \App\AccountType::with(['accounts' => function($query){
        $query->leftJoin('bank_accounts', 'chart_master.account_code', '=', 'bank_accounts.account_code')
        ->whereNull('bank_accounts.account_code');
     }])->get();

返回了account_types,但没有返回任何accounts

我尝试使用DB::enableQueryLog()获取查询日志,这就是输出

Array ( [0] => Array ( [query] => select * from `chart_master` left join `bank_accounts` on `chart_master`.`account_code` = `bank_accounts`.`account_code` where `bank_accounts`.`account_code` is null [bindings] => Array ( ) [time] => 1.66 ) [1] => Array ( [query] => select * from `chart_types` [bindings] => Array ( ) [time] => 1.03 ) [2] => Array ( [query] => select * from `chart_master` left join `bank_accounts` on `chart_master`.`account_code` = `bank_accounts`.`account_code` where `chart_master`.`account_type` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) and `bank_accounts`.`account_code` is null [bindings] => Array ( [0] => 11 [1] => 12 [2] => 21 [3] => 22 [4] => 31 [5] => 32 [6] => 33 [7] => 38 [8] => 39 [9] => 61 [10] => 1101 [11] => 1102 [12] => 1103 [13] => 1104 [14] => 1105 [15] => 1201 [16] => 1202 [17] => 1203 [18] => 1209 [19] => 2101 [20] => 2102 [21] => 2103 [22] => 2104 [23] => 2105 [24] => 2106 [25] => 2107 [26] => 2108 [27] => 2109 [28] => 2110 [29] => 2111 [30] => 2112 [31] => 2201 [32] => 2202 [33] => 2203 [34] => 2204 [35] => 2205 [36] => 2206 [37] => 3101 [38] => 3102 [39] => 3201 [40] => 3301 [41] => 3302 [42] => 3303 [43] => 3304 [44] => 3305 [45] => 3801 [46] => 3901 [47] => 4101 [48] => 4201 [49] => 4202 [50] => 4203 [51] => 4204 [52] => 4205 [53] => 4209 [54] => 4301 [55] => 4401 [56] => 5101 [57] => 5102 [58] => 5201 [59] => 5202 [60] => 12011 [61] => 12012 [62] => 12013 [63] => 12091 [64] => 12092 [65] => 12093 [66] => 12094 [67] => 110301 [68] => 110302 [69] => 110303 [70] => 110304 [71] => 110305 [72] => 120110 [73] => 120120 [74] => 120130 [75] => 120910 [76] => 120920 [77] => 120930 [78] => 120940 [79] => 210101 ) [time] => 2.57 ) )

查询似乎没有问题,但仍未检索到accounts

该日志数据仅包含两个查询生成器查询

\ App \ Account.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Account extends Model
{
    protected $table = "chart_master";


    public function type()
    {
        return $this->belongsTo('App\AccountType', 'account_type');
    }
}

\ App \ AccountType.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class AccountType extends Model
{
    protected $table = "chart_types";

    public function accounts()
    {
        return $this->hasMany('App\Account', 'account_type');
    }
}

1 个答案:

答案 0 :(得分:0)

Welp,似乎我为自己进行的查询过于复杂,试图执行与原始查询完全相同的查询,但没有看到解决此类简单问题的替代解决方案,即排除一堆记录。

无论如何,以下是实现所需操作的代码:

$accountTypesWithAccountsExcludingBankAccounts 
     = \App\AccountType::has('accounts')->with(['accounts' => function($query){
        $query->whereNotIn('chart_master.account_code', \App\BankAccount::all()->pluck('account_code') );
     }])->get();

我仍然不知道为什么我最初编写的代码无法正常工作。