我正在开发一款跟踪您登录时间的游戏。它可以节省数据库的登记时间以及退房日期。
这是一个游戏,就像捕获旗帜一样,只有我不想要它做的是计算得分在18:00(下午6点)和09:00(9点)之间的时间。这适用于每一天,而不仅仅是一次。
分数以秒为单位显示。很容易说这是办理登机手续和退房时间之间的差异(减去每天18:00-09:00之间的时间)。
有人是高级SQL日期计算的专家,可以帮助我吗?请!
这是我的基本查询,没有时间减法:
SELECT
SUM(TIMESTAMPDIFF(SECOND,sessions.checkin,IFNULL(sessions.checkout,NOW())))
AS score
FROM `sessions`
GROUP BY `user_id`
答案 0 :(得分:1)
它不会很漂亮(如果您要执行此操作,可能需要添加functions以提高查询的可读性)
假设您没有跨越多天的登录信息,则可以执行以下操作
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的登记和第3天的8:55结帐,则无效一旦它跨越多天的可数时间,计算不会结束 - 对于每天跨越可数次数的记录,您需要从结果中减去不可数秒的数量。如果您需要帮助,请告诉我。
上面的查询应该相对便宜地运行 - 假设你在整个表上运行它,所以它会进行表扫描,事实上有很多重复的计算它看起来很大并不重要。这些计算在内存中发生,没有额外的I / O,并且应该比磁盘I / O快几个数量级(与原始查询的执行时间相比,让我们知道您是否会看到性能下降)。 / p>