取得PHP和MySQL的总时数

时间:2018-09-19 04:41:26

标签: php mysql datetime

我有下表

id | user_id | date                 | status
1  |    53   | 2018-09-18 06:59:54  | 1
2  |    62   | 2018-09-18 07:00:16  | 1
3  |    53   | 2018-09-18 09:34:12  | 2
4  |    53   | 2018-09-18 12:16:27  | 1
5  |    53   | 2018-09-18 18:03:19  | 2
6  |    62   | 2018-09-18 18:17:41  | 2

我想获取总工作时间(从日期范围开始)并按user_id进行分组

更新

系统不“要求”退房,因此如果只有一个值,我们可以设置默认退房时间,比如19:00:00?如果不是这样,我每天都可以在21:00:00进行检查,是否没有结帐时间可以在19:00:00手动插入它?

更新2

我在“状态”表中添加了一个新字段,因此日期的第一个登机状态为1,第二次登机状态为2

因此,如果用户在一天中第三次签到,则状态将再次为1等。

我希望这会使事情变得简单

谢谢

2 个答案:

答案 0 :(得分:0)

使用TIMESTAMPDIFF功能

查询更像:

SELECT t1.user_id, TIMESTAMPDIFF(HOUR,t1.date,t2.date) as difference
FROM your_table t1
       INNER JOIN your_table t2 on t1.user_id = t2.user_id
Group By t1.user_id

您可以将此作为首选项TimeStampDiff

答案 1 :(得分:0)

如果一天之内发生多次入住和退房,则该用户:

  • 利用Correlated Subquery,我们可以为每个“ checkin_time”找到对应的“ checkout_time”。
  • 此外,请注意使用Ifnull()Timestamp()函数等,以在没有相应条目的情况下将默认的“ checkout_time”视为 19:00:00
  • 然后,将此增强的数据集视为Derived Table,我们根据user_iddate对数据集进行分组。日期( yyyy-mm-dd )可以使用Date()函数来确定。
  • 最终,将Timestampdiff()函数与 Sum 聚合一起使用,以确定user_id在特定日期的总工作秒数。
  • 您可以轻松地将总秒数转换为小时数(在应用程序代码中或在查询本身处)(秒数除以3600)。
  • 我更喜欢使用秒进行计算的原因,因为 Timestampdiff()函数仅返回整数。因此,在多次签入/签出的情况下,可能会出现截断错误。

使用以下查询(将your_table替换为您的实际表名):

SELECT inner_nest.user_id, 
       DATE(inner_nest.checkin_time) AS work_date, 
       SUM(TIMESTAMPDIFF(SECOND, 
                         inner_nest.checkin_time,
                         inner_nest.checkout_time)) AS total_work_seconds  
FROM 
(
  SELECT t1.user_id, 
         t1.date as checkin_time, 
         t1.status, 
         IFNULL( ( 
                  SELECT t2.date 
                  FROM your_table AS t2 
                  WHERE t2.user_id = t1.user_id 
                    AND t2.status = 2 
                    AND t2.date > t1.date 
                    AND DATE(t2.date) = DATE(t1.date) 
                  ORDER BY t2.date ASC LIMIT 1
                 ), 
                 TIMESTAMP(DATE(t1.date),'19:00:00')
               ) AS checkout_time 
  FROM `your_table` AS t1 
  WHERE t1.status = 1
) AS inner_nest 
GROUP BY inner_nest.user_id, DATE(inner_nest.checkin_time)

其他:以下解决方案适用于只有一次入住并在同一天进行相应退房的情况。

  • 您首先需要根据user_iddate对数据集进行分组。日期( yyyy-mm-dd )可以使用Date()函数来确定。

  • 现在使用Min()Max()之类的聚合函数来查找user_id在特定日期的开始和结束时间。

  • 最终,使用Timestampdiff()函数来确定user_id在特定日期的工作时间(关闭时间和开始时间之间的差异)

尝试以下查询(将your_table替换为您的实际表名)

SELECT user_id, 
       DATE(`date`) AS working_date, 
       TIMESTAMPDIFF(HOUR, MIN(`date`), MAX(`date`)) AS working_hours 
FROM your_table 
GROUP BY 
  user_id, 
  DATE(`date`)