MySQL查询过多次轮班 - 更简单的方法?

时间:2012-04-17 01:50:38

标签: mysql sql database

我有一些与MySQL有关的报告,以下代码是我目前解决问题的方法。

在我开始考虑工作人员轮班时间超过午夜时,这似乎很直接,所以必须调整查询。现在我有php根据日期/时间跨度生成不同的查询,如下所示:

如果工作班次在同一天下降(即:2天上午8点至晚上8点):

SELECT <select statements>
FROM <from statements>
WHERE
(
    (Date = '2012-04-16' AND Time BETWEEN '08:00:00' AND '20:00:00')
    OR
    (Date = '2012-04-02' AND Time BETWEEN '08:00:00' AND '20:00:00')
);

如果班次超过午夜就变得复杂(即:2天晚上8点到8点):

SELECT <select statements>
FROM <from statements>
WHERE
(
    (
        (Date = '2012-04-16' AND Time >= '20:00:00')
        OR
        (Date = '2012-04-17' AND Time <= '08:00:00')
    )
    OR
    (
        (Date = '2012-04-17' AND Time >= '20:00:00')
        OR
        (Date = '2012-04-18' AND Time <= '08:00:00')
    )
);

您可以想象,这些查询在我添加到报告中的每一天都变得非常冗长。必须有一个更聪明的方法来做到这一点 - 任何人都可以提供任何见解吗?

2 个答案:

答案 0 :(得分:1)

如果你想拥有更优雅的代码,这部分:

    (Date = '2012-04-16' AND Time >= '20:00:00')
    OR
    (Date = '2012-04-17' AND Time <= '08:00:00')

可以改为:

    (Date, Time) >= (DATE('2012-04-16'), TIME('20:00:00'))
    AND 
    (Date, Time) <= (DATE('2012-04-17'), TIME('08:00:00'))

(Date, Time)上的复合索引对您和上述版本都有帮助。


如果您有多个条件,例如:

SELECT <select statements>
FROM <from statements>
WHERE
(
    (
        (Date = '2012-04-16' AND Time >= '20:00:00')
        OR
        (Date = '2012-04-17' AND Time <= '08:00:00')
    )
    OR
    .....
    OR 
    (
        (Date = '2012-05-27' AND Time >= '20:00:00')
        OR
        (Date = '2012-05-28' AND Time <= '08:00:00')
    )
)

你可以把它变成:

SELECT <select statements>
FROM <from statements>
  CROSS JOIN
      ( SELECT TIME('20:00:00') AS start_time
             , TIME('08:00:00') AS end_time
      ) AS cc
  JOIN
      ( SELECT d                   AS this_day
             , d + INTERVAL 1 DAY  AS next_day
        FROM
          ( SELECT DATE('2012-04-16') AS d
          UNION ALL
            ...
          UNION ALL
            SELECT '2012-05-27'
          ) AS s 
      ) AS selected
     ON  (Date, Time) >= (selected.this_day, cc.start_time)
     AND (Date, Time) <= (selected.next_day, cc.end_time  )

答案 1 :(得分:0)

我最近遇到了这样的问题,我必须编写一个包括夜班在内的三个班次的代码,这也涉及到今天和第二天。

这是代码:

Select *, Case When Shifts = 'Night' and 
(DATEPART(HOUR,DATEADD(day,1,SystemDate_PST))>='00'               //next day data// 
and DATEPART(HOUR,DATEADD(day,1,SystemDate_PST)) <='06')
THEN DATEADD(DAY,-1, SystemDate_PST) else SystemDate_PST               // to show next day data as current day data//
end as Timings from 
(
Select *,
case 
when DATEPART(HOUR, SystemDate_PST)*60+DATEPART(MINUTE, SystemDate_PST) between
06*60+30 and 14*60+30 then 'Morning'
When DATEPART(HOUR, SystemDate_PST)*60+DATEPART(MINUTE, SystemDate_PST) between
23*60-30 and  23*60+60 then 'Night' 
when datepart(HOUR,dateadd(day,1,SystemDate_PST)) >='00' 
and datepart(HOUR,dateadd(day,1,SystemDate_PST))*60 + DATEPART(MINUTE, SystemDate_PST
<=07*60-30 then 'Night'
else 'Noon' 
end as Shifts from (Select * from Table) a )b

我的排班时间是: 上午:06:30AM-14:29 PM 中午:14:30PM-22:29 PM 晚上:22:30 PM- 06:29 AM