我有2个简单的表格。第一表包含工人的缺勤情况。
tbl_absences
+----+-------------+------------+-----------------------+
| id | id_employee | day_number | is_covered_by_a_range |
+----+-------------+------------+-----------------------+
| 1 | 1 | 18 | true/false |
| 2 | 1 | 3 | true/false |
| 3 | 2 | 21 | true/false |
| 4 | 1 | 13 | true/false |
| 5 | 2 | 22 | true/false |
| 6 | 1 | 10 | true/false |
| 7 | 1 | 7 | true/false |
.....
第二张表包含该工人患病并且是中间休假的时间段(介于range_start
和range_end
之间的天数)
tbl_sick_leave
+----+-------------+-------------+-----------+
| id | id_employee | range_start | range_end |
+----+-------------+-------------+-----------+
| 1 | 1 | 4 | 8 |
| 2 | 1 | 13 | 18 |
| 3 | 1 | 15 | 21 |
| 4 | 2 | 9 | 12 |
.....
我希望表is_covered_by_a_range
中的列tbl_absences
保留一个布尔值: true 如果该天被tbl_sick_leave
中的任何范围所覆盖,并且<如果不是,则strong> false 。
为了仅针对工作程序1进行更新,我的方法是查询如下内容:
update tbl_absences AS a
SET a.is_covered_by_a_range=(EXISTS(
SELECT * FROM tbl_sick_leave AS s
WHERE s.id_employee=1 AND a.day_number BETWEEN s.range_start AND s.range_end
))
WHERE a.id_employee=1
注意:tbl_sick_leave
可以容纳一个涵盖特定日期的范围。
可以做得更好吗?对于大表,我担心这种查询的性能。
测试1
tbl_absences
+----+-------------+------------+-----------------------+
| id | id_employee | day_number | is_covered_by_a_range |
+----+-------------+------------+-----------------------+
| 1 | 1 | 5 | -1 |
| 2 | 1 | 10 | -1 |
+----+-------------+------------+-----------------------+
tbl_sick_leave
+----+-------------+-------------+-----------+
| id | id_employee | range_start | range_end |
+----+-------------+-------------+-----------+
| 1 | 1 | 2 | 6 |
+----+-------------+-------------+-----------+
使用此查询将更新两行:
update tbl_absences AS a
SET a.is_covered_by_a_range=(EXISTS(
SELECT * FROM tbl_sick_leave AS s
WHERE s.id_employee=1 AND a.day_number BETWEEN s.range_start AND s.range_end
))
WHERE a.id_employee=1
结果(is_covered_by_a_range
中的正确值):
tbl_absences
+----+-------------+------------+-----------------------+
| id | id_employee | day_number | is_covered_by_a_range |
+----+-------------+------------+-----------------------+
| 1 | 1 | 5 | 1 |
| 2 | 1 | 10 | 0 |
+----+-------------+------------+-----------------------+
答案 0 :(得分:1)
您可以使用public int nextEven(int h){
int n = ThreadLocalRandom.current().nextInt(1 + (h / 2)); // 0 to (h / 2) inclusive
return n * 2; // n * 2 is even (or zero).
}
JOIN
很难预测性能,但是您当然应该从两个表中UPDATE tbl_absences AS a
LEFT JOIN tbl_sick_leave AS s ON a.id_employee = s.id_employee AND a.day_number BETWEEN s.range_start AND s.range_end
SET a.is_covered_by_a_range = s.id IS NOT NULL
WHERE a.id_employee = 1
上的索引开始。如果这还不够好,那么在id_employee
中(id_employee, day_number
上的复合索引可能会有所帮助。如果不是,请发布tbl_absences
查询的输出。