2 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個贊
您不能在 Laravel 中選擇具有相同名稱的兩行。第二個將覆蓋第一個。請改用別名。
$users = DB::table('users as u')
->select('u.*', 'm1.id as membership_id')
->join('memberships as m1','u.id','=','m1.user_id')
->leftJoin('memberships as m2', function($join){
$join->on('u.id', '=', 'm2.user_id')
->where(function ($query) {
$query->whereColumn('m1.expire_at','<','m2.expire_at')
->orWhere(function ($query) {
$query->whereColumn('m1.expire_at','=','m2.expire_at')
->whereColumn('m1.id','<','m2.id');
});
});
})
->whereNull('m2.id')
->get();
注意:我還在連接中封裝了orWhere(),以避免混淆 AND/OR 的順序。
同樣有效的是在選擇中使用不同的順序。例如,您可以使用以下內(nèi)容:
$query->select([
'm1.*',
'm1.id as membership_id',
'u.*'
])
它將返回兩個表的所有列以及新membership_id列。但是如果users表上有一列的名稱與表上的列相似memberships,則只users返回表列(例如created_at)。返回列表中最后一個。

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個贊
編輯:
正如@Namoshek 所提到的,您不應(yīng)該選擇所有內(nèi)容,因?yàn)槟?SQL 查詢中存在重復(fù)鍵問題。我修改了我的答案,使其與@RaymondNijland 的答案相匹配。順便說一句,即使對于表用戶,您也應(yīng)該準(zhǔn)確地選擇您需要的內(nèi)容。不僅針對重復(fù)鍵問題,還針對 SQL 查詢的速度。我們考慮得還不夠多,但它可以很快對大量結(jié)果產(chǎn)生影響。
從數(shù)據(jù)庫發(fā)送到 PHP 服務(wù)器的數(shù)據(jù)更少 = 更快
你應(yīng)該試試這個:
DB::table('users as u')
->select('u.*', 'm1.id as membership_id')
->join('memberships as m1','u.id','=','m1.user_id')
->leftJoin('memberships as m2', function ($join) {
$join->on('u.id', '=', 'm2.user_id')
->on(function($join) {
$join->on('m1.id', '<', 'm2.id')
->on(function($join) {
$join->on('m1.expire_at', '<', 'm2.expire_at')
->orOn('m1.expire_at', '=', 'm2.expire_at');
});
});
})
->whereNull('m2.id')
->toSQL()
如本頁 Laravel 文檔中所述:https ://laravel.com/api/5.8/Illuminate/Database/Query/JoinClause.html#method_on
您可以將閉包傳遞給該on()方法,并且orOn()您可以在此閉包中使用該方法。
我測試了它,它給出了與您的 SQL 查詢相同的結(jié)果。
- 2 回答
- 0 關(guān)注
- 193 瀏覽
添加回答
舉報