ThinkPHP5.1使用union之后使用paginate报错

入坑

    • 因为项目需求必须使用union关联查询,源代码如下:
      • 这里的$data最终是用paginate函数自动生成分页,但是这里报错了,使用select就可以正常获取到值。

因为项目需求必须使用union关联查询,源代码如下:

    $data = $student_model->field(implode(',', $fieldArr))->alias('student_sell')
            ->join($commonJoinArr)
            ->where($commonWhereArr)->order($order)->group($group)
            ->where($where)
            ->unionAll([$this->getUnionAllSql($request, $type, $flow_type, 0)])
            ->paginate();
            
            其中getUnionAllSql代码如下(也就是生成需要执行的sql语句,unionAll里面只需要传入sql语句即可):
            $sql = $student_model->field(implode(',', $fieldArr))->alias('student_sell')
            ->join($commonJoinArr)
            ->where($commonWhereArr)->order($order)->group($group)
            ->where($where)
            ->buildSql();
            return $sql;

    

这里的$data最终是用paginate函数自动生成分页,但是这里报错了,使用select就可以正常获取到值。

           于是开始懵逼,按理说就是这样子,后面又把查询方式换成了子查询的方式
            $data = $student_model->field(implode(',', $fieldArr))->alias('student_sell')
            ->join($commonJoinArr)
            ->where($commonWhereArr)->order($order)->group($group)
            ->where($where)
            ->unionAll([$this->getUnionAllSql($request, $type, $flow_type, 0)])
            ->buildSql();
            Db::table("$data ss")->paginate();

构建出来的sql语句本来希望是这种

		SELECT
			`student_sell`.*, student_sell.id id,
			`student_sell`.`student_name`,
			`school`.`school_name`,
			`contract`.`status`,
			`course`.`course_name`,
			`class`.`class_name`,
			`class`.`class_pa`,
			`student_class`.`isdelete`,
			`flow`.`auditor_content`,
			`flow`.`create_time`,
			`flow`.`data_id`,
			`flow`.`type`,
			`flow`.`auditor`,
			`flow`.`next_person`,
			flow.id flow_id,
			flow.create_time create_time,
			`change_class_record`.`flow_id`,
			`flow`.`change_class_record_id`,
			`flow`.`auditor_status`,
			`flow`.`result_status`,
			`flow`.`change_flow_type`,
			`change_class_record`.`note`
		FROM
			`rms_student_sell` `student_sell`
		INNER JOIN `rms_school` `school` ON `student_sell`.`school_id` = `school`.`id`
		INNER JOIN `rms_student_sell_contract` `contract` ON `contract`.`student_sell_id` = `student_sell`.`id`
		INNER JOIN `rms_student_course` `student_course` ON `student_course`.`student_id` = `student_sell`.`id`
		INNER JOIN `rms_course` `course` ON `course`.`id` = student_course.course_id
		AND contract.course_id = course.id
		LEFT JOIN `rms_student_class` `student_class` ON `student_sell`.`id` = `student_class`.`student_id`
		LEFT JOIN `rms_classs` `class` ON `student_class`.`class_id` = `class`.`id`
		INNER JOIN `rms_change_class_record` `change_class_record` ON `change_class_record`.`old_student_id` = `student_sell`.`id`
		INNER JOIN `rms_flow` `flow` ON `flow`.`data_id` = student_course.id
		AND flow.change_class_record_id = change_class_record.id
		WHERE
			`student_sell`.`business_status` = '14'
		AND `student_class`.`isdelete` = '0'
		AND `flow`.`person_type` = '0'
		AND `flow`.`auditor` = '1'
		AND `flow`.`type` = '3'
		AND `change_flow_type` = '1'
		GROUP BY
			`flow`.`id`
		UNION
			(
				(
					SELECT
						`student_sell`.*, student_sell.id id,
						`student_sell`.`student_name`,
						`school`.`school_name`,
						`contract`.`status`,
						`course`.`course_name`,
						`class`.`class_name`,
						`class`.`class_pa`,
						`student_class`.`isdelete`,
						`flow`.`auditor_content`,
						`flow`.`create_time`,
						`flow`.`data_id`,
						`flow`.`type`,
						`flow`.`auditor`,
						`flow`.`next_person`,
						flow.id flow_id,
						flow.create_time create_time,
						`change_class_record`.`flow_id`,
						`flow`.`change_class_record_id`,
						`flow`.`auditor_status`,
						`flow`.`result_status`,
						`flow`.`change_flow_type`,
						`change_class_record`.`note`
					FROM
						`rms_student_sell` `student_sell`
					INNER JOIN `rms_school` `school` ON `student_sell`.`school_id` = `school`.`id`
					INNER JOIN `rms_student_sell_contract` `contract` ON `contract`.`student_sell_id` = `student_sell`.`id`
					LEFT JOIN `rms_student_class` `student_class` ON `student_sell`.`id` = `student_class`.`student_id`
					LEFT JOIN `rms_classs` `class` ON `student_class`.`class_id` = `class`.`id`
					INNER JOIN `rms_change_class_record` `change_class_record` ON `change_class_record`.`old_student_id` = `student_sell`.`id`
					INNER JOIN `rms_course_renew` `course_renew` ON `course_renew`.`student_id` = `student_sell`.`id`
					INNER JOIN `rms_course` `course` ON `course`.`id` = course_renew.course_id
					AND contract.course_id = course.id
					INNER JOIN `rms_flow` `flow` ON `flow`.`data_id` = course_renew.id
					AND flow.change_class_record_id = change_class_record.id
					WHERE
						`student_sell`.`business_status` = '14'
					AND `student_class`.`isdelete` = '0'
					AND `flow`.`person_type` = '0'
					AND `flow`.`auditor` = '1'
					AND `flow`.`type` = '3'
					AND `change_flow_type` = '3'
					GROUP BY
						`flow`.`id`
				)
			)
	

事实没有想得那么美好,只要使用paginate函数就会在前面自动加上,追踪源码

ThinkPHP5.1使用union之后使用paginate报错_第1张图片
发现sql语句前面增加了

SELECT
	COUNT(s.*) AS tp_count
FROM
这时候才想到,分页之前要求总条数,但是对于union查询来说求count的时候字段会重复。

于是去官方文档查看
ThinkPHP5.1使用union之后使用paginate报错_第2张图片
果然传入的分页总条数,

 $data = $student_model->field(implode(',', $fieldArr))->alias('student_sell')
            ->join($commonJoinArr)
            ->where($commonWhereArr)->order($order)->group($group)
            ->where($where)
            ->unionAll([$this->getUnionAllSql($request, $type, $flow_type, 0)])
            ->paginate(1, 2, ['query' => $request->param()]);

希望遇到坑的同学,可以跳出这个坑。

你可能感兴趣的:(PHP)