2009-09-17 2 views
1

Мой первоначальный ответ на эту проблему состоял в том, чтобы его сценарий. Вместо использования SQL я погрузился в Python и нормализовал их. Мне любопытно, может ли кто-нибудь придумать решение, использующее SQL.SQL - нормализация временных меток к рабочим часам

Если дата происходит вне рабочего времени, я хочу нормализовать дату на следующий рабочий день. Я сделаю это очень просто и скажу, что рабочее время с 9:00 до 18:00 с понедельника по пятницу. Все, что находится за пределами этих часов, находится вне рабочего времени.

Что должно происходить, так это то, что они меняются так, что 2 часа дня в субботу становится 9 утра в понедельник утром (первое законное время на рабочей неделе). 7 вечера в среду становится 9 утра в четверг утром. и т. д. Давайте проигнорируем праздники.

Образец данных:

mysql> select mydate from mytable ORDER by mydate; 
+---------------------+ 
| mydate    | 
+---------------------+ 
| 2009-09-13 17:03:09 | 
| 2009-09-14 09:45:49 | 
| 2009-09-15 09:57:28 | 
| 2009-09-16 21:55:01 | 
+---------------------+ 
4 rows in set (0.00 sec) 

Первая дата является воскресенье поэтому она должна быть нормирована на 2009-09-14 09:00:00

Вторая дата нормально, это в 9 утра на понедельник.

Третья дата в порядке, это в 9 утра во вторник.

Четвертая дата в 9 вечера (за пределами наших рабочих часов 9 утра до 6 вечера) в среду и должна быть преобразована в 9 утра в четверг утром.

ответ

1

Я думаю, что вы лучше с вашим решением Python ... но я люблю вызовы :)

select mydate 
    , case dayadjust 
-- BUG 
--   when 0 then mydate 
-- BUG 
      when 0 then case 
       when hour(mydate)<9 
         then date_add(from_days(to_days(mydate)), 
           INTERVAL 9 HOUR) 
       else mydate 
      end 
-- BUG SQUASHED 
      else date_add(from_days(to_days(mydate) + dayadjust), 
         INTERVAL 9 HOUR) 
     end as mynewdate 
from (
     select mydate 
      , case 
        when addday>=moreday then addday 
        else moreday 
       end as dayadjust 
     from (
       select mydate 
        , weekday(mydate) as w 
        , hour(mydate) as h 
        , case weekday(mydate) 
          when 6 then 1 
          when 5 then 2 
          when 4 then 
            case 
             when hour(mydate) >= 18 then 3 
             else 0 
            end 
          else 0 
         end as addday 
        , case when hour(mydate)>=18 then 1 else 0 end as moreday 
       from mytable 
       order by mydate 
     ) alias1 
) alias2 

Проверено на MySQL

$ mysql tmp < phil.sql 
mydate mynewdate 
2009-09-12 17:03:09  2009-09-14 09:00:00 
2009-09-12 21:03:09  2009-09-14 09:00:00 
2009-09-13 17:03:09  2009-09-14 09:00:00 
2009-09-14 09:45:49  2009-09-14 09:45:49 
2009-09-15 09:57:28  2009-09-15 09:57:28 
2009-09-16 21:55:01  2009-09-17 09:00:00 
2009-09-17 11:03:09  2009-09-17 11:03:09 
2009-09-17 22:03:09  2009-09-18 09:00:00 
2009-09-18 12:03:09  2009-09-18 12:03:09 
2009-09-18 19:03:09  2009-09-21 09:00:00 
2009-09-19 06:03:09  2009-09-21 09:00:00 
2009-09-19 16:03:09  2009-09-21 09:00:00 
2009-09-19 19:03:09  2009-09-21 09:00:00 
+0

Нашли ошибку в моем SQL заявление для раз до 9 утра в рабочие дни (например, «2009-09-16 6:07:08»). Сообщение отредактировано с помощью решения – pmg

0

Не знаете, почему вы хотите это сделать, но если это необходимо для всех данных в вашей базе данных, вам нужен триггер. Я бы установил таблицу, чтобы вытащить из нее, указывающую часы работы, и вы можете использовать эту таблицу для определения следующего действительного рабочего дня и дня. (Я мог бы даже подумать над созданием таблицы, в которой вам точно указано, что следующий рабочий день и час для каждой возможности, это не так сильно меняется, возможно, придется обновлять один раз в год, если вы меняете праздничные дни на следующий год или если вы меняете общие рабочие часы. По предварительной оценке вы, вероятно, сэкономите время на обработку этого.). Я также хотел бы использовать ваш скрипт, потому что лучше фиксировать данные до того, как они будут введены, но вам нужен триггер, чтобы гарантировать, что данные из любого источника (и рано или поздно будут изменения из источников, отличных от вашего приложения) удовлетворяют данным правила целостности.

0

Я не думаю, что вы можете сделать это в одном запросе, но вы можете попробовать это:

-- Mon-Thu, after 17:00 
-- Set date = next day, 9:00 
UPDATE 
    myTable 
SET 
    mydate = DATE_ADD(DATE_ADD(DATE(date), INTERVAL 1 DAY), INTERVAL 9 HOUR) 
WHERE 
    TIME(mydate) >= 17 
    AND DAYOFWEEK(mydate) IN (1,2,3,4) 

-- Mon-Fri, before 9:00 
-- Set date = the same day, 9:00 
UPDATE 
    myTable 
SET 
    mydate = DATE_ADD(DATE(date), INTERVAL 9 HOUR) 
WHERE 
    TIME(mydate) < 9 
    AND DAYOFWEEK(mydate) IN (1,2,3,4,5) 

-- Fri, after 17:00, Sat, Sun 
-- Set date = monday, 9.00 
UPDATE 
    myTable 
SET 
    mydate = DATE_ADD(DATE_ADD(DATE(date), INTERVAL 3 DAY), INTERVAL 9 HOUR) 
WHERE 
    (TIME(mydate) >= 17 
    AND DAYOFWEEK(mydate) = 5) 
    OR DAYOFWEEK(mydate) IN (6,7) 
Смежные вопросы