基于时间范围匹配的工单表与班次表关联查询方案
Got it, let's figure out how to map your work orders to their correct shifts. First, let's clarify the tables you're working with (I've formatted them into readable tables for clarity):
Work Orders Table
| Date | TimeOfEntry | Plant | ManufacturingLine | OrderNumber |
|---|---|---|---|---|
| 2017-06-13 | 11:56:58 | 3120 | D19 | 100015234 |
| 2017-06-13 | 12:12:18 | 3120 | MIX | 100016098 |
| 2017-06-13 | 12:17:59 | 3120 | D16 | 100015218 |
| 2017-06-13 | 12:21:01 | 3120 | D19 | 100015234 |
| 2017-06-13 | 12:22:23 | 3120 | D19 | 100016017 |
| 2017-06-13 | 12:43:52 | 3120 | WW2 | 100015543 |
| 2017-06-13 | 12:45:49 | 3120 | WW2 | 100015543 |
| 2017-06-13 | 13:00:26 | 3120 | W43 | 100015574 |
| 2017-06-13 | 13:01:51 | 3120 | PRE | 100016148 |
| 2017-06-13 | 13:05:53 | 3120 | MIX | 100016095 |
Shifts Table
| Plant | Shift | StartTime | EndTime |
|---|---|---|---|
| 3101 | Day | 06:01:00.0000000 | 14:00:00.0000000 |
| 3120 | Day | 06:01:00.0000000 | 14:00:00.0000000 |
| 3150 | Day | 06:01:00.0000000 | 14:00:00.0000000 |
| 3160 | Day | 06:01:00.0000000 | 14:00:00.0000000 |
| 3170 | Day | 06:01:00.0000000 | 14:00:00.0000000 |
| 3101 | Afternoon | 14:01:00.0000000 | 22:00:00.0000000 |
| 3120 | Afternoon | 14:01:00.0000000 | 22:00:00.0000000 |
| 3150 | Afternoon | 14:01:00.0000000 | 22:00:00.0000000 |
| 3160 | Afternoon | 14:01:00.0000000 | 22:00:00.0000000 |
| 3170 | Afternoon | 14:01:00.0000000 | 22:00:00.0000000 |
| 3101 | Night | 22:01:00.0000000 | 06:00:00.0000000 |
| 3120 | Night | 22:01:00.0000000 | 06:00:00.0000000 |
| 3150 | Night | 22:01:00.0000000 | 06:00:00.0000000 |
| 3160 | Night | 22:01:00.0000000 | 06:00:00.0000000 |
| 3170 | Night | 22:01:00.0000000 | 06:00:00.0000000 |
Implementation Solution
The key challenge here is handling the overnight night shift (where StartTime is later than EndTime). Here's a SQL query that works across most databases, with adjustments for your table structure:
For SQL Server
SELECT wo.Date, wo.TimeOfEntry, wo.Plant, wo.ManufacturingLine, wo.OrderNumber, s.Shift AS ShiftName FROM WorkOrders wo JOIN Shifts s ON wo.Plant = s.Plant WHERE -- Handle regular shifts (Day/Afternoon: StartTime <= EndTime) (s.StartTime <= s.EndTime AND CAST(CAST(wo.Date AS DATETIME) + CAST(wo.TimeOfEntry AS DATETIME) AS TIME) BETWEEN s.StartTime AND s.EndTime) -- Handle overnight Night shifts (StartTime > EndTime) OR (s.StartTime > s.EndTime AND (CAST(CAST(wo.Date AS DATETIME) + CAST(wo.TimeOfEntry AS DATETIME) AS TIME) >= s.StartTime OR CAST(CAST(wo.Date AS DATETIME) + CAST(wo.TimeOfEntry AS DATETIME) AS TIME) <= s.EndTime)) ORDER BY wo.Date, wo.TimeOfEntry;
For MySQL
SELECT wo.Date, wo.TimeOfEntry, wo.Plant, wo.ManufacturingLine, wo.OrderNumber, s.Shift AS ShiftName FROM WorkOrders wo JOIN Shifts s ON wo.Plant = s.Plant WHERE -- Regular shifts (s.StartTime <= s.EndTime AND TIME(CONCAT(wo.Date, ' ', wo.TimeOfEntry)) BETWEEN s.StartTime AND s.EndTime) -- Overnight shifts OR (s.StartTime > s.EndTime AND (TIME(CONCAT(wo.Date, ' ', wo.TimeOfEntry)) >= s.StartTime OR TIME(CONCAT(wo.Date, ' ', wo.TimeOfEntry)) <= s.EndTime)) ORDER BY wo.Date, wo.TimeOfEntry;
Logic Explanation
- Plant Matching: We first join the two tables on the
Plantfield to ensure we only look at shifts relevant to the work order's plant. - Regular Shifts: For Day and Afternoon shifts (where
StartTimeis earlier thanEndTime), we check if the work order's time falls directly between the shift's start and end times. - Overnight Shifts: For Night shifts (which span midnight), we check if the work order's time is either after the shift starts (22:01+) or before the shift ends (06:00-). This accounts for the shift crossing into the next day.
This query will correctly assign every work order to its corresponding shift, including edge cases like entries right at shift boundaries.
内容的提问来源于stack exchange,提问作者Anton Fernando
相关产品推荐
相关产品推荐

