mysql 存储过程之复杂查询

有这样一个场景,一个plan可能对应多个place,多个时间,多条记录,一个用户
表1为:
CREATE TABLE IF NOT EXISTS InspectionPlan (
id char(36) NOT NULL COMMENT ‘巡检计划ID’,
name char(36) NOT NULL COMMENT ‘巡检计划名字’,
status smallint(6) NOT NULL COMMENT ‘巡检计划状态’,
executorUserId char(36) NOT NULL COMMENT ‘执行人员名字’,
times varchar(128) NOT NULL COMMENT ‘时间字符串,若有多个时间字符串用逗号间隔’,
weeks varchar(128) NOT NULL COMMENT ‘星期字符串,一周中占用哪几天,1表示周一,…7表示周日’,
creatAt datetime NOT NULL COMMENT ‘巡检计划创建时间’,
description varchar(128) DEFAULT NULL COMMENT ‘巡检计划描述’,
PRIMARY KEY (id),
KEY rf_user_inspectionPlan (executorUserId),
CONSTRAINT rf_user_inspectionPlan FOREIGN KEY (executorUserId) REFERENCES User (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表2为:
CREATE TABLE IF NOT EXISTS InspectionPlanPlace (
id char(36) NOT NULL,
planId char(36) DEFAULT NULL COMMENT ‘巡检计划ID’,
placeId char(36) DEFAULT NULL COMMENT ‘巡检计划关联的巡检地方ID’,
PRIMARY KEY (id),
KEY rf_inspectionPlanPlace1 (planId),
KEY rf_inspectionPlanPlace2 (placeId),
CONSTRAINT rf_inspectionPlanPlace1 FOREIGN KEY (planId) REFERENCES InspectionPlan (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT rf_inspectionPlanPlace2 FOREIGN KEY (placeId) REFERENCES InspectionPlace (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表3为:
CREATE TABLE IF NOT EXISTS InspectionRecord (
id char(36) NOT NULL COMMENT ‘巡检任务ID’,
planId char(36) DEFAULT NULL COMMENT ‘巡检任务相关联的巡检计划ID’,
creatTime datetime DEFAULT NULL COMMENT ‘开始时间’,
endTime datetime DEFAULT NULL COMMENT ‘结束时间’,
executeUserId char(36) DEFAULT NULL COMMENT ‘用户ID’,
status smallint(6) DEFAULT NULL COMMENT ‘巡检任务状态,1 表示未提交,2表示正常,3表示异常’,
photoUrl text COMMENT ‘巡检图片URL;若有多个用分号分割’,
description char(255) DEFAULT NULL COMMENT ‘巡检任务描述’,
PRIMARY KEY (id),
KEY rf_InspectionRecord1 (executeUserId),
KEY rf_InspectionRecord2 (planId),
CONSTRAINT rf_InspectionRecord1 FOREIGN KEY (executeUserId) REFERENCES User (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT rf_InspectionRecord2 FOREIGN KEY (planId) REFERENCES InspectionPlan (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表4为:
CREATE TABLE IF NOT EXISTS User (
id char(36) NOT NULL,
name varchar(64) DEFAULT NULL,
password varchar(64) DEFAULT NULL,
displayName varchar(128) DEFAULT NULL,
isEnable tinyint(6) DEFAULT ‘1’,
createTime datetime DEFAULT NULL,
updateTime datetime DEFAULT NULL,
mobile varchar(20) NOT NULL,
email varchar(100) DEFAULT NULL,
openId char(36) DEFAULT NULL,
accelCtrlId char(36) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY index_openId (openId),
CONSTRAINT rf_User1 FOREIGN KEY (openId) REFERENCES WeixinUserInfo (openId) ON DELETE SET NULL ON UPDATE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表5为:
CREATE TABLE IF NOT EXISTS InspectionPlace (
id char(36) NOT NULL COMMENT ‘巡检地方ID’,
name char(64) DEFAULT NULL COMMENT ‘巡检地方名字’,
machineId char(36) DEFAULT NULL COMMENT ‘巡检地方关联的打卡ID’,
createTime datetime DEFAULT NULL COMMENT ‘创建时间’,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

下面需要从这五个表中进行planId,开始时间和结束时间来查询这个plan的统计信息。如果分别从这五个表查询信息的话需要对数据库进行了多次访问,从而会降低读写效率。所以, 笔者想用存储过程,先分别从这五个表中抽出相关信息一个视图,再根据筛选条件创建存储过程从视图中查询需要信息。
基本如下:
创建视图1
select plan.id AS id,plan.name AS name,plan.status AS status,plan.executorUserId AS executorUserId,plan.times AS times,plan.weeks AS weeks,plan.creatAt AS creatAt,plan.description AS description,user.displayName AS executorUserName,pp.placeId AS placeId,place.name AS placeName from (((InspectionPlan plan left join InspectionPlanPlace pp on((plan.id = pp.planId))) left join User user on((user.id = plan.executorUserId))) left join InspectionPlace place on((place.id = pp.placeId)));

在视图1的基础上创建视图2:
select vwInspectionPlanWithPlaces.id AS id,vwInspectionPlanWithPlaces.name AS name,vwInspectionPlanWithPlaces.status AS status,vwInspectionPlanWithPlaces.executorUserId AS executorUserId,vwInspectionPlanWithPlaces.executorUserName AS executorUserName,vwInspectionPlanWithPlaces.times AS times,vwInspectionPlanWithPlaces.weeks AS weeks,vwInspectionPlanWithPlaces.creatAt AS creatAt,vwInspectionPlanWithPlaces.description AS description,group_concat(vwInspectionPlanWithPlaces.placeName separator ‘,’) AS placeName,group_concat(vwInspectionPlanWithPlaces.placeId separator ‘,’) AS placeId from vwInspectionPlanWithPlaces group by vwInspectionPlanWithPlaces.id

在视图2的基础上根据筛选条件创建存储过程1:
CREATE PROCEDURE uspQueryStatInspection(
in start_time DATETIME,
in end_time DATETIME,
in pId char(36)
)
BEGIN
select
pp.id as id,
pp.name as name,
pp.status as status,
pp.executorUserId as executorUserId,
pp.executorUserName as executorUserName,
pp.times as times,
pp.weeks as weeks,
pp.creatAt as creatAt,
pp.description as description,
pp.placeName as placeName,
pp.placeId as placeId,
b.missing as missing,
b.success as success,
b.fail as fail,
b.total as total
from (select
r.planId as planId,
count(r.status=1 or null) as missing,
count(r.status=2 or null) as success,
count(r.status=3 or null) as fail,
count(r.status or null) as total
from InspectionRecord r where r.creatTime > start_time and r.creatTime < end_time and r.planId=pid group by planId) b
left join vwInspectionPlanWithPlacesGroup pp on(pp.id=b.planId) ;
END

调用存储过程得到相对应的数据:
call uspQueryStatInspection(‘2017-03-23 17:51:28’,’2019-03-23 17:51:28’,’1’);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值