方法一:先子表用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(HashMap map);
//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 td
td.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
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
)
GROUP BY td.create_dept_id
);
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 )> 0
sys.parent_id is null or sys.parent_id =''
GROUP BY
sys.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博客