1

我有一些关于 MySQL 的报告,下面的代码是我目前对该问题的解决方案。

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

如果工作班次在同一天(即:两天的上午 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')
);

如果轮班超过午夜,它会变得复杂(即:两天的晚上 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')
    )
);

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

4

2 回答 2

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  )
于 2012-04-17T23:17:50.647 回答
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:30 AM - 14:29 PM 中午:14:30 PM - 22:29 PM 晚上:22:30 PM - 06:29 AM

于 2018-11-20T13:05:26.037 回答