php - Mysql中条件检查之间有多个条件吗?有什么办法可以优化这个查询吗?

标签 php mysql subquery query-optimization between

我正在开发报告生成应用程序,我正在根据用户操作使用PHP生成查询。现在我根据工作人员的经验查询详细信息,有不止一种选择的可能性。结果取自连接 5 个表和子查询,我的查询工作正常并获取准确的结果

第一个场景: 员工总经验在 15 到 20 年之间

查询

SELECT sd.staff_ref_id AS staff_code,
       sd.sur,
       sd.staff_name AS Name,
       sq.degree AS Qualification,
       sd.designation,
       d.department_name,
       TIMESTAMPDIFF(MONTH, s.join_date, CURDATE()) AS rec_exp_months,
       sum(spe.years) AS p_exp_yrs,
       sum(spe.months) AS p_exp_months
FROM staff_details sd
LEFT JOIN
  (SELECT s.staff_id,
          group_concat(sq.degree) AS degree
   FROM staff_details s,
        staff_qualification sq
   WHERE s.staff_id = sq.staff_id
   GROUP BY sq.staff_id
   ORDER BY sq.row_num)sq ON sd.staff_id = sq.staff_id
LEFT JOIN staff_department s ON s.staff_id = sd.staff_id
LEFT JOIN department d ON d.department_id =s.depart_id
LEFT JOIN staff_previous_experience spe ON spe.staff_id = sd.staff_id
WHERE <b>((TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 120 AND 180)</b>
GROUP BY staff_ref_id,
         sd.sur,
         sd.staff_name,
         sd.designation,
         d.department_name,
         sq.degree,
         s.join_date

第二种情况:员工总经验介于 10 至 15 年和 15 至 20 年之间

查询

SELECT sd.staff_ref_id AS staff_code,
       sd.sur,
       sd.staff_name AS Name,
       sq.degree AS Qualification,
       sd.designation,
       d.department_name,
       TIMESTAMPDIFF(MONTH, s.join_date, CURDATE()) AS rec_exp_months,
       sum(spe.years) AS p_exp_yrs,
       sum(spe.months) AS p_exp_months
FROM staff_details sd
LEFT JOIN
  (SELECT s.staff_id,
          group_concat(sq.degree) AS degree
   FROM staff_details s,
        staff_qualification sq
   WHERE s.staff_id = sq.staff_id
   GROUP BY sq.staff_id
   ORDER BY sq.row_num)sq ON sd.staff_id = sq.staff_id
LEFT JOIN staff_department s ON s.staff_id = sd.staff_id
LEFT JOIN department d ON d.department_id =s.depart_id
LEFT JOIN staff_previous_experience spe ON spe.staff_id = sd.staff_id
WHERE <b>((TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 120 AND 180
         OR (TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 180 AND 240)</b>
GROUP BY staff_ref_id,
         sd.sur,
         sd.staff_name,
         sd.designation,
         d.department_name,
         sq.degree,
         s.join_date

注意:上面突出显示的区域,我正在检查总体经验,我正在将数据库中的输入和结果转换为月份并检查条件

问题:变暗区域是从 php 生成的查询,我正在使用之间查询..基于从经验字段中选择的选项数量,之间查询会自动生成..
有什么办法可以优化这个..?
是否有一个选项可以在多个条件的查询选项之间使用...?

我的查询执行时间是 0.0663 秒

等待回复、建议和意见 提前致谢

最佳答案

感觉这会给你带来与第一个 WHERE 相同的效果:

WHERE sd.join_date >= CURDATE() - INTERVAL 180 MONTH
  AND sd.join_date  < CURDATE() - INTERVAL 120 MONTH

并且有INDEX(join_date)

如果是这样,那么它就简单多了,速度肯定更快。

突出显示的子查询中的GROUP BY是不必要的。

由于 GROUP BYORDER BY row_num 可能无效并被忽略。

LEFT JOIN 之后的派生表中似乎不需要 s。

为什么要分别计算BETWEEN 120 AND 180BETWEEN 180 AND 240?看起来它们可以合并在一起。

如果它不更快,那么进行我在评论中建议的清理,然后让我们重新开始。请为每个表提供SHOW CREATE TABLE

关于php - Mysql中条件检查之间有多个条件吗?有什么办法可以优化这个查询吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39039125/

相关文章:

MySQL 子查询/连接

php - 使用php上传照片无需重新加载

php ->!= PHP运算符,不等于不大于怎么写?

sql - 如何在子查询中使用 Coalesce 进行字符串连接?

php - Nginx 服务器 : upstream timed out (10060: A connection attempt failed)

php - Zend|Db\Sql|表达式在 Zend SL 语句中不起作用

mysql - 以下查询没有给我预期的结果,请帮助我

php - 如何在 PHP 中重新格式化日期时间字符串?

PHP : Dropdown not insert into table

php - PHP echo 中的引号破坏了 HTML 值