Расширенный SQL вычитание даты - PullRequest
2 голосов
/ 13 декабря 2010

Я работаю над игрой, которая отслеживает, как долго вы вошли в систему. Она сохраняет время регистрации в базе данных, а также дату выезда.

Это игра, что-то вроде захвата флага, единственное, чего я не хочу, это считать время между 18:00 (18:00) и 09:00 (9:00) счетом. Это происходит каждый день, а не только один раз.

Счет отображается в секундах. Легко сказать, что это разница между временем регистрации заезда и отъезда (минус время между 18: 00-09: 00, для повседневного использования).

Кто-нибудь является экспертом в продвинутых вычислениях даты в SQL и может мне помочь? Пожалуйста!

Это мой основной запрос без вычитания времени:

SELECT
SUM(TIMESTAMPDIFF(SECOND,sessions.checkin,IFNULL(sessions.checkout,NOW()))) 
AS score
FROM `sessions`
GROUP BY `user_id`

1 Ответ

1 голос
/ 13 декабря 2010

Это будет не красиво (вы можете добавить функции для удобства чтения ваших запросов, если вы собираетесь делать это много)

Если у вас нет логинов, которыеВ течение нескольких дней вы можете выполнить следующие действия:

   SELECT
       user_id,
       SUM(
          TIMESTAMPDIFF(SECOND,
             CASE 
                WHEN sessions.checkin < timestamp(date(sessions.checkin), maketime(9,0,0))
                   THEN timestamp(date(sessions.checkin), maketime(9,0,0))
                WHEN sessions.checkin > timestamp(date(sessions.checkin), maketime(18,0,0))
                   THEN timestamp(date(sessions.checkin)+1, maketime(9,0,0))
                ELSE
                   sessions.checkin
             END,
             CASE
                WHEN IFNULL(sessions.checkout, now()) > timestamp(date(IFNULL(sessions.checkout, now())), maketime(18,0,0))
                   THEN timestamp(date(IFNULL(sessions.checkout, now())), maketime(18,0,0))
                WHEN IFNULL(sessions.checkout, now()) < timestamp(date(IFNULL(sessions.checkout, now())), maketime(9,0,0))
                   THEN timestamp(date(IFNULL(sessions.checkout, now()))-1, maketime(18,0,0))
                ELSE
                   IFNULL(sessions.checkout, now())
             END)) AS score
    FROM `sessions`
    GROUP BY `user_id`

. Это не работает, если входы в систему, которые охватывают несколько дней или, если быть точным, запрос могут работать с входами в систему, которые охватывают несколько дней, например, регистрация в 18:05 в первыйдень и оформить заказ в 8:55 на третий день, но как только он переходит в исчисляемое время в несколько дней, вычисление не заканчивается - для каждой записи, которая охватывает счетное время в течение нескольких дней, необходимо вычесть количество неисчислимых секунд изрезультат.Дайте мне знать, если вам нужна помощь.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...