方法一:先子表用count函数统计数据 再配合find_in_set函数 、sum函数统计全部数据。count统计本级数据,sum配合find_in_set是同统计本级以及子级的数据
方法二:直接使用count配合find_in_set再加上判断FIND_IN_SET( dept.id, t.parent_path )来统计本级和本级及其下级数据
SELECT dept.id, //本级数据 count( CASE WHEN FIND_IN_SET( dept.id, t.parent_path )= 1 THEN 1 END ) bdw, //本级数据及下级数据 count( CASE WHEN FIND_IN_SET( dept.id, t.parent_path )> 0 THEN 1 END ) lj FROM sys_department dept LEFT JOIN ( SELECT tq.org_Id, sd.parent_path, sd.id deptId FROM `tq_meet` tq LEFT JOIN sys_department sd ON tq.org_id = sd.id ) t ON FIND_IN_SET( dept.id, t.parent_path )> 0 GROUP BY dept.id
先用count统计数量再用sum计算和
select fresult.* from ( select sd.id ,sd.`name` deptName, IFNULL(sum(result.PersuasiveNum),0) PersuasiveNum, IFNULL(sum(result.DsrgzdwNum),0) DsrgzdwNum from sys_department sd left join ( select dTable.create_dept_id,dept.parent_path,dTable.PersuasiveNum PersuasiveNum,dTable.DsrgzdwNum DsrgzdwNum from ( SELECT td.create_dept_id, count( td.create_dept_id ) PersuasiveNum, count(case when td.dsr_gzdw IS NOT NULL and td.dsr_gzdw != '' then 1 end) DsrgzdwNum FROM tq_ddcwf td GROUP BY td.create_dept_id )dTable left join sys_department dept on dTable.create_dept_id =dept.id ) result on FIND_IN_SET(sd.id,result.parent_path)>0 where sd.id is not null and sd.status=1 GROUP BY sd.id ) fresult order by fresult.PersuasiveNum desc
3、传入部门id查出本级及其所以下级的部门id 用来实现统计数据 最好添加上
GROUP BY td.create_dept_id来分类
and td.create_dept_id in (select id from ( with recursive departments as ( select a.id,a.name,a.parent_id,b.name as parent_name from sys_department a left join sys_department b on a.parent_id=b.id where a.id in (${deptId}) union all select bb.id,bb.name,bb.parent_id,bb.parent_name from ( select a.id,a.name,a.parent_id,b.name as parent_name from sys_department a left join sys_department b on a.parent_id=b.id ) as bb,departments as h where h.id=bb.parent_id ) select dep.id,dep.name,dep.parent_id,dep.parent_name from departments as dep ) xx )
此方法的前提是表有parent_path这个字段,以下为生成此字段
//更新所有单位的上级路径 sysDepartmentMapper.updataParentPath(new HashMap<>()); //mapper文件 int updataParentPath(HashMapmap); //xml代码 update sys_department sd set sd.parent_path =getParentList('sys_department', sd.id)
getParentList为数据库中的函数。
CREATE DEFINER=`root`@`%` FUNCTION `getParentList`(tableName varchar(64),rootId varchar(100)) RETURNS varchar(1000) CHARSET utf8 BEGIN DECLARE fid varchar(100) default ''; DECLARE str varchar(4000) default rootId; IF tableName = 'sys_department' THEN WHILE rootId is not null do SET fid =(SELECT parent_id FROM sys_department WHERE id = rootId); IF fid is not null THEN SET str = concat(str, ',', fid); SET rootId = fid; ELSE SET rootId = fid; END IF; END WHILE; END IF; return str; END
update sys_department sd
set sd.parent_path =getParentList('sys_department', sd.id)
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'str' at row 1
当数据库中数据父子结构乱的时候可用以下查出结构混乱的数据并删除
SELECT * FROM sys_department depart LEFT JOIN sys_department sd2 on depart.parent_id=sd2.id LEFT JOIN sys_department sd3 on sd2.parent_id=sd3.id LEFT JOIN sys_department sd4 on sd3.parent_id=sd4.id LEFT JOIN sys_department sd5 on sd4.parent_id=sd5.id LEFT JOIN sys_department sd6 on sd5.parent_id=sd6.id WHERE depart.id=sd2.id or depart.id=sd3.id or depart.id=sd4.id or depart.id=sd5.id or depart.id=sd6.id
统计还有生成临时表在统计
CREATE TEMPORARY TABLE IF NOT EXISTS tempresult AS ( select count(CASE WHEN YEARWEEK(td.create_time,1) = YEARWEEK(now(),1)-1 THEN 0 END) lastWeekSum, count(CASE WHEN YEARWEEK(td.create_time,1) = YEARWEEK(now(),1) THEN 0 END) thisWeekSum, count(CASE WHEN MONTH(td.create_time) = MONTH(now()) THEN 0 END) thisMonthSum, td.create_dept_name createDeptName, td.create_dept_id createDeptId FROM tq_ddcwf tdtd.cllx='面包车' and (MONTH(td.create_time) = MONTH(now()) or YEARWEEK(td.create_time,1) = YEARWEEK(now(),1)-1 or YEARWEEK(td.create_time,1) = YEARWEEK(now(),1)) and td.hzrs>4 ); SELECT IFNULL( SUM( t.lastWeekSum ), 0 ) AS lastWeekSum, IFNULL( SUM( t.thisWeekSum ), 0 ) AS thisWeekSum, IFNULL( SUM( t.thisMonthSum ), 0 ) AS thisMonthSum, sys.NAME AS createDeptName FROM sys_department sys RIGHT JOIN ( SELECT temp1.lastWeekSum, temp1.thisWeekSum, temp1.thisMonthSum, temp1.createDeptName, temp1.createDeptId, sd.parent_path, sd.parent_id FROM tempresult temp1 LEFT JOIN sys_department sd ON sd.id = temp1.createDeptId ) t ON FIND_IN_SET( sys.id, t.parent_path )> 0and td.create_dept_id in (select id from ( with recursive departments as ( select a.id,a.name,a.parent_id,b.name as parent_name from sys_department a left join sys_department b on a.parent_id=b.id where a.id in (${deptId}) union all select bb.id,bb.name,bb.parent_id,bb.parent_name from ( select a.id,a.name,a.parent_id,b.name as parent_name from sys_department a left join sys_department b on a.parent_id=b.id ) as bb,departments as h where h.id=bb.parent_id ) select dep.id,dep.name,dep.parent_id,dep.parent_name from departments as dep ) xx ) GROUP BY td.create_dept_id GROUP BY sys.id; sys.parent_id is null or sys.parent_id =''
WITH recursive dates AS ( SELECT DATE('开始时间') AS date UNION ALL SELECT date + INTERVAL 1 DAY FROM dates WHERE date < DATE('结束时间') ), table1_data AS ( SELECT DATE(create_time) AS date, SUM(value) AS total_value FROM table1 WHERE DATE(create_time) BETWEEN DATE('开始时间') AND DATE('结束时间') GROUP BY DATE(create_time) ), table2_data AS ( SELECT DATE(create_time) AS date, COUNT(*) AS total_count FROM table2 WHERE DATE(create_time) BETWEEN DATE('开始时间') AND DATE('结束时间') GROUP BY DATE(create_time) ), table3_data AS ( SELECT DATE(create_time) AS date, AVG(price) AS average_price FROM table3 WHERE DATE(create_time) BETWEEN DATE('开始时间') AND DATE('结束时间') GROUP BY DATE(create_time) ) SELECT dates.date, COALESCE(t1.total_value, 0) AS table1_total_value, COALESCE(t2.total_count, 0) AS table2_total_count, COALESCE(t3.average_price, 0) AS table3_average_price FROM dates LEFT JOIN table1_data t1 ON dates.date = t1.date LEFT JOIN table2_data t2 ON dates.date = t2.date LEFT JOIN table3_data t3 ON dates.date = t3.date ORDER BY dates.date;
实战
WITH recursive dates AS ( SELECT DATE('2023-08-15') AS date UNION ALL SELECT date + INTERVAL 1 DAY FROM dates WHERE date < DATE('2023-08-18') ), table1_data AS ( SELECT DATE( create_time ) AS date, count( CASE WHEN cllx = '行人' OR cllx = '电动二轮车' THEN 1 END ) AS 'xingrenOrdderlun', count( CASE WHEN cllx = '三轮' OR cllx = '四轮' THEN 1 END ) AS 'sanlunOrsilun', count( CASE WHEN cllx = '面包车' THEN 1 END ) AS 'mianbaoche', count( CASE WHEN cllx = '电动车临牌' THEN 1 END ) AS 'ddclinpai' FROM tq_ddcwf WHERE DATE(create_time) BETWEEN DATE('2023-08-15') AND DATE('2023-08-18') GROUP BY DATE(create_time) ), table2_data AS ( SELECT DATE( create_time ) AS date, IFNULL( COUNT( 1 ), 0 ) AS 'sjmyjd' FROM tq_sjmyjd_table WHERE DATE(create_time) BETWEEN DATE('2023-08-15') AND DATE('2023-08-18') GROUP BY DATE(create_time) ), table3_data AS ( SELECT DATE( create_time ) AS date, IFNULL( COUNT(*), 0 ) AS 'wjaqd' FROM tq_wjaqd WHERE DATE(create_time) BETWEEN DATE('2023-08-15') AND DATE('2023-08-18') GROUP BY DATE(create_time) ) SELECT dates.date, COALESCE(t1.xingrenOrdderlun, 0) AS xingrenOrdderlun, COALESCE(t1.sanlunOrsilun, 0) AS sanlunOrsilun, COALESCE(t1.mianbaoche, 0) AS mianbaoche, COALESCE(t1.ddclinpai, 0) AS ddclinpai, COALESCE(t2.sjmyjd, 0) AS sjmyjd, COALESCE(t3.wjaqd, 0) AS wjaqd FROM dates LEFT JOIN table1_data t1 ON dates.date = t1.date LEFT JOIN table2_data t2 ON dates.date = t2.date LEFT JOIN table3_data t3 ON dates.date = t3.date ORDER BY dates.date;
上面使用嵌套结果映射 但分页不支持嵌套结果映射可以修改为嵌套select可参考
分页导致Mybatis数据不一致(使用了关联查询collection)_高树悲风的博客-CSDN博客
CREATE TEMPORARY TABLE 创建的临时表是一个独立的表对象,会在当前会话结束或显式删除表时被销毁。这意味着,临时表只在当前会话中可见,并且不能被其他会话访问。因此,您可以使用相同的表名创建临时表,在不同的会话中保证不会发生冲突。
另一方面,WITH 子句生成的临时表仅在查询语句的上下文中存在,也称为 "公用表表达式" (Common Table Expression, CTE)。这意味着,虽然临时表在查询中被引用了多次,但它只是查询中的一个临时结果集,并没有被创建为一个独立的表对象。因此,它不能在查询之外的上下文中被引用或操作。
因此,如果您需要在当前会话中创建一个独立的临时表,以供多个查询或操作使用,那么 CREATE TEMPORARY TABLE 将是更适合的选择。如果您只需要在一个查询中使用临时表,那么 WITH 子句创建的临时表将更加方便。
CREATE TEMPORARY TABLE a1 AS ( SELECT zh.* FROM `user2023` zh LEFT JOIN sys_user suer ON zh.accounts = suer.user_name WHERE suer.id IS NULL ); INSERT INTO user_copy (id, user_name, name, status, user_type, platform, password) SELECT UUID(), accounts, name, 1, '1', '1', 'dezhoujiaojing@123' FROM a1; INSERT INTO user_role (id, user_id, role_id, role_name) SELECT UUID(), c.id, '1', '1' FROM ( SELECT b.id FROM a1 a LEFT JOIN user_copy b on a.accounts = b.user_name) c; -- DROP TEMPORARY TABLE IF EXISTS a1;
WITH town AS ( SELECT *FROM sys_department WHERE unit_type = 1 AND xz_level = 4 and xzqh=#{xzqh} ) SELECT * FROM town WHERE #{djzs} LIKE CONCAT('%', town.name, '%');
上一篇:MAC 安装配置使用Tomcat