Laravel Excel导出时如何为查询字段添加if..else逻辑及解决字典表关联报错
解决方案
报错原因
你多次关联同一张baseinfos表时没有设置别名,SQL无法区分两个关联的同名表,同时select语句中两次取baseinfos.bas_value字段名重复,因此触发1066错误。
方案1:修改SQL关联逻辑(查询时直接转换)
给每个关联的baseinfos表设置独立别名,查询字段也设置对应别名即可解决冲突:
public static function getAccounts($id) { $records = DB::table('members') ->where('mys_creator_id',$id) ->where('mys_olp_id',4) ->join('my_students', 'members.mbr_usr_id', '=', 'my_students.mys_mbr_id') ->join('students', 'members.mbr_usr_id', '=', 'students.std_mbr_id') // 学历关联baseinfos,别名degree_info ->join('baseinfos as degree_info', 'students.std_degree_id', '=', 'degree_info.bas_id') // 性别关联baseinfos,别名gender_info ->join('baseinfos as gender_info', 'members.mbr_gender_id', '=', 'gender_info.bas_id') ->select( 'members.mbr_name', 'members.mbr_family', 'members.mbr_father_name', 'members.mbr_national_code', 'members.mbr_birthday', 'members.mbr_phone', 'members.mbr_mobile', 'members.mbr_post_code', 'members.mbr_prv_id', 'members.mbr_cit_id', 'gender_info.bas_value as gender', // 性别文本别名gender 'members.mbr_address', 'degree_info.bas_value as degree', // 学历文本别名degree 'students.std_grade_id', 'students.std_filed_id', 'students.std_major_id', 'students.std_school', 'students.std_education_type_id', 'my_students.mys_paid_price' ) ->get() ->toArray(); return $records; }
如果部分id允许为空,可以把join换成leftJoin避免数据被过滤。
方案2:导出层做映射转换(更灵活,推荐)
配合laravel-excel的行映射功能处理,不需要修改原有查询逻辑,适合需要转换的id字段较多的场景:
- 提前把
baseinfos的id和文本映射关系一次性查询出来 - 在导出类的
map方法中逐字段转换即可
// laravel-excel导出类示例 namespace App\Exports; use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\WithMapping; class AccountsExport implements FromCollection, WithMapping { protected $baseInfoMap; public function __construct() { // 一次性获取所有baseinfos映射,可加缓存优化性能 $this->baseInfoMap = \DB::table('baseinfos')->pluck('bas_value', 'bas_id')->toArray(); } public function collection() { // 调用你原有无需转换的查询方法即可 return Member::getAccounts(request()->id); } public function map($account): array { return [ $account->mbr_name, $account->mbr_family, $account->mbr_father_name, $account->mbr_national_code, // 性别转换 $this->baseInfoMap[$account->mbr_gender_id] ?? '未知', // 学历转换 $this->baseInfoMap[$account->std_degree_id] ?? '未知', // 其他需要转换的字段同理添加即可 // ... $account->mys_paid_price ]; } }
这个方案后续新增需要转换的id字段时,不需要调整SQL语句,直接在映射数组中添加对应规则即可,维护成本更低。
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

