Mysql 条件检查之间有多个条件?有什么办法可以优化这个查询吗?
More than one condition in Mysql Between Condition Checking? Is there any way to optimize this query?
我正在处理报告生成应用程序,我正在根据用户操作使用 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
注意:上面突出显示的区域,我正在检查总经验,我正在将数据库的输入和结果转换为月份并检查条件
问题:Darken Area 是从 php 生成的查询,我正在使用 between query..基于从经验字段中选择了多少选项, between query会自动生成..
有什么办法可以优化这个..?
是否有一个选项可以在多个条件查询中使用 between 选项...?
我的查询执行时间是 0.0663 秒
等待回应、建议和忠告
提前致谢
感觉和第一个效果一样WHERE
:
WHERE sd.join_date >= CURDATE() - INTERVAL 180 MONTH
AND sd.join_date < CURDATE() - INTERVAL 120 MONTH
并且有INDEX(join_date)
.
如果是这样,那么它就简单多了,一定会更快。
突出显示的子查询中的 GROUP BY
是不必要的。
ORDER BY row_num
可能无效并被忽略,因为 GROUP BY
。
在 LEFT JOIN
.
之后派生的 table 中似乎不需要 s
为什么要分别计算BETWEEN 120 AND 180
和BETWEEN 180 AND 240
?好像可以合二为一
如果不是更快,那么进行我在评论中建议的清理,让我们重新开始。请为每个 table.
提供 SHOW CREATE TABLE
我正在处理报告生成应用程序,我正在根据用户操作使用 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
注意:上面突出显示的区域,我正在检查总经验,我正在将数据库的输入和结果转换为月份并检查条件
问题:Darken Area 是从 php 生成的查询,我正在使用 between query..基于从经验字段中选择了多少选项, between query会自动生成..
有什么办法可以优化这个..?
是否有一个选项可以在多个条件查询中使用 between 选项...?
我的查询执行时间是 0.0663 秒
等待回应、建议和忠告 提前致谢
感觉和第一个效果一样WHERE
:
WHERE sd.join_date >= CURDATE() - INTERVAL 180 MONTH
AND sd.join_date < CURDATE() - INTERVAL 120 MONTH
并且有INDEX(join_date)
.
如果是这样,那么它就简单多了,一定会更快。
突出显示的子查询中的 GROUP BY
是不必要的。
ORDER BY row_num
可能无效并被忽略,因为 GROUP BY
。
在 LEFT JOIN
.
为什么要分别计算BETWEEN 120 AND 180
和BETWEEN 180 AND 240
?好像可以合二为一
如果不是更快,那么进行我在评论中建议的清理,让我们重新开始。请为每个 table.
提供SHOW CREATE TABLE