使用数据库:MYSQL 5.7.27
参考资料:
数据库~Mysql派生表注意的几点~关于百万数据的慢查询问题 https://blog.csdn.net/weixin_34146410/article/details/93984487 子查询:在一个查询中嵌套另一个查询,则另一个查询成为子查询,也叫内部查询 派生表:在FROM子句中使用子查询时,从子查询返回的结果集将用作临时表。 该表称为派生表 当查询的复杂sql数据量大时,把 派生表 改成 子查询, 查询速度将变快 因为派生表不能走索引,子查询可以走索引 在数据量比较小时: 派生表查询速度比子查询快一倍 派生表sql:SELECT t0.department_name, t0.department_id, -- 上一年度正式人员 IFNULL(t1.beforeYearNormalCount,0) as beforeYearNormalCount, -- 当前正式人员 IFNULL(t2.normalCount,0) as normalCount, -- 较上年新增正式人员数 IFNULL(t2.normalCount,0)-IFNULL(t1.beforeYearNormalCount,0) as normalCompareBeforeYearCount, -- 试用人员 IFNULL(t3.probationCount,0) as probationCount, -- 人员折算总计 IFNULL(t4.sumCoefficient,0) as sumCoefficient from ( select MIN(a.department_name) as department_name, a.department_id, count(1) from ding_talk_employee a where a.department_name !='' -- and dimission_remarks !='不统计' group by a.department_id ORDER BY department_name ) as t0 LEFT JOIN ( -- 上一年度正式人员 SELECT a.department_id, count( 1 ) AS beforeYearNormalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = DATE_ADD('2021-01-01 00:00:00', INTERVAL - 1 YEAR ) AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) AS t1 on t1.department_id=t0.department_id LEFT JOIN ( -- 当前正式人员 SELECT a.department_id, count( 1 ) AS normalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) AS t2 on t2.department_id=t0.department_id LEFT JOIN ( -- 试用人员 SELECT a.department_id, count(1) AS probationCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status = '2' GROUP BY a.department_name ) AS t3 on t3.department_id=t0.department_id LEFT JOIN ( SELECT a.department_id, SUM(dtea.coefficient) AS sumCoefficient FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' GROUP BY a.department_id ) AS t4 on t4.department_id=t0.department_id
派生表转换成子查询后的sql:
SELECT tu.department_name, tu.department_id, -- 上一年度正式人员 tu.beforeYearNormalCount, -- 当前正式人员 tu.normalCount, -- 较上年新增正式人员数 IFNULL(tu.normalCount,0)-IFNULL(tu.beforeYearNormalCount,0) as normalCompareBeforeYearCount, -- 试用人员 tu.probationCount, -- 人员折算总计 tu.sumCoefficient FROM ( SELECT MIN(t0.department_name) as department_name, t0.department_id, IFNULL( ( -- 上一年度正式人员 SELECT count( 1 ) AS beforeYearNormalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = DATE_ADD('2021-01-01 00:00:00', INTERVAL - 1 YEAR ) AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) ,0) as beforeYearNormalCount, IFNULL( ( -- 当前正式人员 SELECT count( 1 ) AS normalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) ,0) as normalCount, IFNULL( ( -- 试用人员 SELECT count(1) AS probationCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status = '2' GROUP BY a.department_name ) ,0) as probationCount, IFNULL( ( SELECT SUM(dtea.coefficient) AS sumCoefficient FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' GROUP BY a.department_id ) ,0) as sumCoefficient FROM ding_talk_employee t0 WHERE t0.department_name !='' -- and dimission_remarks !='不统计' GROUP BY t0.department_id ORDER BY t0.department_name ) as tu