在列中进行子查询
1、在一个表中有多个员工ID,比如一个下单员工,一个修改订单的员工,可以使用在列中进行子查询,具体如下:
( SELECT staff_name FROM sp_staff_basic WHERE sp_staff_basic.id = qc_return_progress_record.created_by ) returnProcessName, LEFT JOIN sp_staff_basic ON sp_staff_basic.id = qc_returnrervice.updated_by
2、left join 自己的表,比如说在一个表中,有一个出发时间字段,又有一个到达时间字段,两个表所对应的节点不一致,但是两个表都记录在订单表中,比如订单的一个状态为出发吗,一个状态为到达,我们需要计算路途中所花的时长,left join 自己的表,就可以取出两个节点所对应的时间,具体如下:
select sp_staff_usework.attach_group attachGroup,COUNT(sp_staff_usework.attach_group) countFrequency,sp_staff_basic.id staffId from (SELECT * from or_order_state_record where or_order_state_record.state_type=3) n1 LEFT JOIN (SELECT * from or_order_state_record where or_order_state_record.state_type=4) n2 on n1.order_id=n2.order_id LEFT JOIN sp_staff_basic on sp_staff_basic.id=n1.created_by LEFT JOIN sp_staff_usework on sp_staff_usework.staff_id=n1.created_by where TIMESTAMPDIFF(MINUTE,n1.created_date,n2.created_date)>3 GROUP BY sp_staff_usework.attach_group
这种方法还可以用来做统计表,表中有多个统计字段的,比如我下面做的客服的服务质量表:
SELECT sp_staff_basic.id staffId, sp_staff_usework.attach_group attachGroup, t1.countFrequency timeoutAudit, t2.countFrequency timeOutList, t3.countMis countMis, t4.countOrderChange countOrderChange, t5.countPeople countPeople, sp_staff_basic.staff_name staffName, sp_staff_usework.position_code positionCode, sp_staff_usework.position_class postionClass, sp_company.id companyId, sp_company.company_name companyName from sp_staff_basic LEFT JOIN sp_staff_usework on sp_staff_usework.staff_id=sp_staff_basic.id LEFT JOIN( select sp_staff_usework.attach_group attachGroup,COUNT(sp_staff_usework.attach_group) countFrequency,sp_staff_basic.id staffId from (SELECT * from or_order_state_record where or_order_state_record.state_type=3) n1 LEFT JOIN (SELECT * from or_order_state_record where or_order_state_record.state_type=4) n2 on n1.order_id=n2.order_id LEFT JOIN sp_staff_basic on sp_staff_basic.id=n1.created_by LEFT JOIN sp_staff_usework on sp_staff_usework.staff_id=n1.created_by <where> <if test="param.startCreateDate != null"> AND n1.created_date <![CDATA[ >= ]]> #{param.startCreateDate,jdbcType=TIMESTAMP} </if> <if test="param.endCreateDate != null"> AND n1.created_date <![CDATA[ < ]]> date_add(#{param.endCreateDate,jdbcType=TIMESTAMP},interval 1 day) </if> and TIMESTAMPDIFF(MINUTE,n1.created_date,n2.created_date)>3 </where> GROUP BY sp_staff_usework.attach_group )t1 on sp_staff_usework.attach_group=t1.attachGroup LEFT JOIN( select sp_staff_usework.attach_group attachGroup,COUNT(sp_staff_usework.attach_group) countFrequency,sp_staff_basic.id staffId from (SELECT * from or_order_state_record where or_order_state_record.state_type=0) n1 LEFT JOIN (SELECT * from or_order_state_record where or_order_state_record.state_type=3) n2 on n1.order_id=n2.order_id LEFT JOIN sp_staff_basic on sp_staff_basic.id=n1.created_by LEFT JOIN sp_staff_usework on sp_staff_usework.staff_id=n1.created_by <where> <if test="param.startCreateDate != null"> AND n1.created_date <![CDATA[ >= ]]> #{param.startCreateDate,jdbcType=TIMESTAMP} </if> <if test="param.endCreateDate != null"> AND n1.created_date <![CDATA[ < ]]> date_add(#{param.endCreateDate,jdbcType=TIMESTAMP},interval 1 day) </if> and TIMESTAMPDIFF(MINUTE,n1.created_date,n2.created_date)>3 </where> GROUP BY sp_staff_usework.attach_group )t2 on sp_staff_usework.attach_group=t2.attachGroup LEFT JOIN ( SELECT COUNT(qc_mistakenum.mistakenum_id) countMis,qc_mistakenum.staff_id staffId,qc_mistakenum.created_date from qc_mistakenum <where> <if test="param.startCreateDate != null"> AND qc_mistakenum.created_date <![CDATA[ >= ]]> #{param.startCreateDate,jdbcType=TIMESTAMP} </if> <if test="param.endCreateDate != null"> AND qc_mistakenum.created_date <![CDATA[ < ]]> date_add(#{param.endCreateDate,jdbcType=TIMESTAMP},interval 1 day) </if> </where> ) t3 on t3.staffId=sp_staff_basic.id LEFT JOIN ( SELECT count(qc_orderchange.order_id) countOrderChange,qc_orderchange.created_by,qc_orderchange.created_date from qc_orderchange <where> <if test="param.startCreateDate != null"> AND qc_orderchange.created_date <![CDATA[ >= ]]> #{param.startCreateDate,jdbcType=TIMESTAMP} </if> <if test="param.endCreateDate != null"> AND qc_orderchange.created_date <![CDATA[ < ]]> date_add(#{param.endCreateDate,jdbcType=TIMESTAMP},interval 1 day) </if> </where> ) t4 on t4.created_by=sp_staff_basic.id LEFT JOIN ( select qc_complaint_people.comp_people_id,count(qc_complaint_people.comp_people_id) countPeople,qc_complaint_record.created_date from qc_complaint_people LEFT JOIN sp_staff_basic on sp_staff_basic.id=qc_complaint_people.comp_people_id LEFT JOIN qc_complaint_record on qc_complaint_record.comp_id=qc_complaint_people.comp_id <where> <if test="param.startCreateDate != null"> AND qc_complaint_record.created_date <![CDATA[ >= ]]> #{param.startCreateDate,jdbcType=TIMESTAMP} </if> <if test="param.endCreateDate != null"> AND qc_complaint_record.created_date <![CDATA[ < ]]> date_add(#{param.endCreateDate,jdbcType=TIMESTAMP},interval 1 day) </if> </where> GROUP BY qc_complaint_people.comp_people_id ) t5 on t5.comp_people_id=sp_staff_basic.id left join sp_company on sp_company.id=sp_staff_usework.company_id <where> <if test="param.companyId != null"> and sp_company.id = #{param.companyId,jdbcType=VARCHAR} </if> <if test="param.staffId != null and param.staffId != ''"> and sp_staff_basic.id = #{param.staffId,jdbcType=INTEGER} </if> <if test="param.positionCode != null and param.positionCode != ''"> and sp_staff_usework.position_code = #{param.positionCode,jdbcType=INTEGER} </if> and (sp_staff_usework.position_code='KHFWZX_KFDDDY' or sp_staff_usework.position_code='KHFWZX_ZJKFDDDY' or sp_staff_usework.position_code='KHFWZX_GJKFDDDY' or sp_staff_usework.position_code='ALL_ZGSKFGJJL' or sp_staff_usework.position_code='ALL_ZGSKFJL' or sp_staff_usework.position_code='KHFWZX_ZSKFDDDY' ) </where> ORDER BY sp_staff_basic.id
最后的原型为,具体是使用员工去查询他的职位,通过职位去筛选其他的,具体见上sql脚本:
还有一个为服务满意度的
服务满意度的做了好久,在 AND 与 OR 的合用与业务逻辑上卡了蛮久的时间
首先
我们需要过滤出需要回访的
需要回访的为:
待回访跟踪中仅包含:电话回访-待回访/未接通;短信回访-超时未提交/不满意-且电话回访为待回访的/非常不满意-且电话回访为待回访的,见列表中的集中组合字段
只有在列表中的字段需要进行回访,其他的直接过滤到完成回访的列表,且还需要过滤点击回访,回访结果为未接通字段
所以在
待回访的sql脚本中我们使用的过滤条件为:
WHERE or_task_node.node_type = 8 AND ( cs_customer.default_return_type IN (0, 1) AND qc_returnrervice.sms_return_result IN (2, 7, 9, 3) AND qc_returnrervice.phone_return_result IN (2, 3) AND ( qc_return_satisfied_record.return_result IS NULL OR qc_return_satisfied_record.return_result = 2 ) ) GROUP BY or_rescue_order.id ORDER BY qc_returnrervice.created_date DESC
回访完成后,需要将其他结果与上面过滤条件过滤掉的字段信息全部进行显示,所以用 AND(A OR B)的结构进行筛选
WHERE or_task_node.node_type = 8 AND ( ( qc_returnrervice.sms_return_result NOT IN (2, 7, 9, 3) AND qc_returnrervice.phone_return_result NOT IN (2, 3) ) OR ( qc_returnrervice.sms_return_result IN (2, 7, 9, 3) AND qc_returnrervice.phone_return_result IN (2, 3) AND qc_return_satisfied_record.return_result IN (0, 1) ) ) GROUP BY or_rescue_order.id ORDER BY qc_returnrervice.created_date DESC
进行相反的过滤,这样就能展示出来所有的回访信息