首先需求是这样的,而且标题这一行是可以做增删改操作的,所以是动态的。
假设标题列是固定的,sql如下
SELECT d.`onduty_time`, (CASE t.`onduty_name` WHEN '区值班领导' THEN p.`name` ELSE NULL END) '区值班领导', (CASE t.`onduty_name` WHEN '局值班领导' THEN p.`name` ELSE NULL END) '局值班领导', (CASE t.`onduty_name` WHEN '值班科长' THEN p.`name` ELSE NULL END) '值班科长', (CASE t.`onduty_name` WHEN '值班主任' THEN p.`name` ELSE NULL END) '值班主任' FROM onduty_access_type t INNER JOIN onduty_type_person_r r ON r.`type_id` = t.`id` INNER JOIN onduty_person p ON p.id = r.`person_id` INNER JOIN onduty_arrange_duty d ON d.tp_rid = r.id 关键部分就是(CASE t.`onduty_name` WHEN '区值班领导' THEN p.`name` ELSE NULL END) '区值班领导'但是要写活,sql如下
-- 1、申明@sql,相当于定义了一个变量 SET @sql=NULL; -- 2、拼接,这就把之前的标题行写活并且拼接起来了 SELECT GROUP_CONCAT(DISTINCT CONCAT_WS('"','(CASE t.`onduty_name` WHEN ',t.`onduty_name`, ' THEN p.`name` ELSE NULL END) as ',t.`onduty_name`,'')) INTO @sql FROM onduty_access_type t ; --查询变量@sql SELECT @sql; CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。 CONCAT_WS()是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。如果有另外的查询列,比如我这里的时间,把sql写全,如下
SET @sql = CONCAT('select d.`onduty_time`,',@sql,' FROM onduty_access_type t LEFT JOIN onduty_type_person_r r ON r.`type_id` = t.`id` LEFT JOIN onduty_person p ON p.id = r.`person_id` RIGHT JOIN onduty_arrange_duty d ON d.tp_rid = r.id where d.delete_flag = 0 AND r.`report`=1 '); SELECT @sql;如果有其他查询条件呢:
--还是要先声明一下变量 SET @onduty_name=NULL; SET @start_time = NULL; SET @end_time = NULL; --这里就是先if判断,然后再拼接查询条件 IF onduty_name IS NOT NULL AND onduty_name <> '' THEN SET @onduty_name = onduty_name; SET @sql = CONCAT(@sql, ' and t.`onduty_name`=\'',@onduty_name,'\''); END IF; IF start_time IS NOT NULL AND start_time <> '' THEN SET @start_time = start_time; SET @sql = CONCAT(@sql,' and d.`onduty_time` <=\'',@start_time,'\''); END IF; IF end_time IS NOT NULL AND end_time <> '' THEN SET @end_time = end_time; SET @sql = CONCAT(@sql,' and d.`onduty_time` <=\'',@end_time,'\''); END IF; SELECT @sql;最后执行拼接出来的sql
-- 使用预执行 PREPARE 声明 stmt PREPARE stmt FROM @sql; -- 开始执行 EXECUTE stmt; -- 清除 DEALLOCATE PREPARE stmt;写到这本以为就可以了,但是在mybatis.xml中执行的时候一直报语法错误,只能改变策略,在逻辑层中先拼接sql,然后再在mapper.xml中执行
@Override public Map<String,Object> getOndutyListCheck(OndutyPerson ondutyPerson) { Map<String, Object> map = new HashMap<>();//填写返回信息 List<Map<String,Object>> ondutyResultList =null; StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilderP = new StringBuilder(); List<String> ondutyAccessTypes = null; String sql = null; try { //获取所有的值班类型 ondutyAccessTypes = ondutyAccessTypeMapper.selectDutyAccessType(ondutyPerson); //将获取到的值班类型动态拼接 for (int i = 0; i <ondutyAccessTypes.size() ; i++) { stringBuilder.append (",GROUP_CONCAT((CASE t.`onduty_name` WHEN '"+ondutyAccessTypes.get(i)+"' THEN p.`name` ELSE null END)) as '"+ondutyAccessTypes.get(i)+"'"); } sql = " DISTINCT d.`onduty_time` as '时间' "+stringBuilder+" FROM onduty_access_type t LEFT JOIN " + " onduty_type_person_r r ON r.`type_id` = t.`id` " + " LEFT JOIN onduty_person p ON p.id = r.`person_id` " + " RIGHT JOIN onduty_arrange_duty d ON d.tp_rid = r.id where t.`organization`='"+ ondutyPerson.getOrganization()+"' AND d.delete_flag = '0' AND r.`report`='1' "; //添加相关的查询条件 stringBuilderP.append(sql); if (StringUtils.isNotBlank(ondutyPerson.getOndutyName())){ stringBuilderP.append(" and t.`onduty_name`='"+ondutyPerson.getOndutyName()+"'"); } if (ondutyPerson.getStartTime()!=null){ stringBuilderP.append(" and d.`onduty_time` >='"+ DateUtil.getUtilDateString(ondutyPerson.getStartTime(),"yyyy-MM-dd HH:mm:ss")+"'") ; } if (ondutyPerson.getEndTime()!=null){ stringBuilderP.append(" and d.`onduty_time` <='"+DateUtil.getUtilDateString(ondutyPerson.getEndTime(),"yyyy-MM-dd HH:mm:ss")+"'") ; } stringBuilderP.append(" GROUP BY d.`onduty_time`"); ondutyResultList = ondutyArrangeDutyMapper.selectOndutyResultList(stringBuilderP); } catch (Exception e) { log.error("值班表查询异常,异常信息为:", e); map.put("success","false"); map.put("msg","失败"); map.put("data",null); return map; } map.put("success","true"); map.put("msg","成功"); map.put("data",ondutyResultList); return map; } <select id="selectOndutyResultList" resultType="java.util.Map" parameterType="String"> select ${res01} </select>