Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 带子句的时间戳_Php_Mysql - Fatal编程技术网

Php 带子句的时间戳

Php 带子句的时间戳,php,mysql,Php,Mysql,我对MySQL查询有一个小问题: 桌子是这样的 id timedate user action 1 2010-01-01 10:01:01 AB991 login 2 2010-01-01 12:01:01 AB991 logout 3 2010-01-01 14:01:01 AB991 login 4 2010-01-01 18:01:01 AB991 logout 5 2010-01-01 10:01:01 ZM991 login 6 201

我对MySQL查询有一个小问题:

桌子是这样的

id  timedate            user  action
1   2010-01-01 10:01:01 AB991 login
2   2010-01-01 12:01:01 AB991 logout
3   2010-01-01 14:01:01 AB991 login
4   2010-01-01 18:01:01 AB991 logout
5   2010-01-01 10:01:01 ZM991 login
6   2010-01-01 10:01:01 ZM991 logout
7   2010-01-02 10:01:01 AB991 login
8   2010-01-02 18:01:01 AB991 logout
9   2010-01-02 10:01:01 ZM991 login
现在,我需要一个查询,或者一些PHP代码,每天为每个用户计算登录和注销之间的分钟差。 但也有一些问题,比如:

可能没有注销日志 有可能一天我有2次登录和2次注销操作或更多。
有一个聪明的解决方案,可能只有MySQL,或者我必须使用PHP并制作一堵代码墙?

一个可能的解决方案如下:

select id, timedate, action
from mytable
where user = 'AB991'
order by timedate
您的PHP代码将按日期获得一个有序列表。算法应该如下所示:

$user = 'AB991';
$stmt = $db->prepare("select id, timedate, action from mytable where user = ? order by timedate");
$stmt->execute(array($user));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$previousTime = "";
foreach ($rows as $row) {
    if ($row["action"] === "login") {
        $previousTime = strtotime($row["timedate"]);
    } else if ($row["action"] === "logout") {
        if ($previousTime === "") {
            //duplicate logout
        } else {
            //add the remaining time to the day when the user logged in
            //add the whole days passed between log in and log out
            //add the start of the last day when the user logged in
            $previousTime = "";
        }
    }
}
问题:

用户可以分别使用不同的会话登录 用户可能无法注销 用户可能会使用其他会话注销
建议:我将修改该表以包含会话id和最后一个操作。当用户执行一个操作时,最后一个操作的时间戳将被更新,因此您将有一个基于会话的数据,其中每一行都会代表自己,显示登录时间和最后一个操作时间。

我认为这个解决方案会有所帮助。作为基础,每个登录都会通过注销来解释这里的代码 我加入所有登录记录排名和所有注销记录排名 因此,如果一个登录计数为1,并且如果由注销计数1流动,则将被选中

select
logIn. *, logOut.* ,
TIMESTAMPDIFF(MINUTE, logIn.timedate, logOut.timeDate) as howLongUserStaysInMinutes

from (SELECT @row_counter1 := 0) x,
     (SELECT @row_counter2 := 0) y,
     (select userLogs.* , @row_counter1 := @row_counter1 +1 as row 
      from userLogs 
      where userLogs.action ='login') as logIn

 left join (select * ,   @row_counter2 :=  @row_counter2 + 1 as row 
             from  userLogs 
             where  userLogs.action = 'logout') as logOut 
             on  logOut.user = logIn.user
             and ( logIn.timedate <= logOut.timedate ||   logOut.timedate is null) 
             and logIn.row = logOut.row
输出:

2.我对注销操作也做了同样的操作

  select id, 
         timedate as timedate, # here you can use max() to get max login in day
         user,
         action, # action will be logout since it specified at where clause
         @row_counter2 := if(@perv_day2 <> DAY( userLogs.timedate ) , 1 , @row_counter1 +1) rankedByDay,
         @perv_day1 := if(@perv_day1 <> DAY( userLogs.timedate ) , DAY( userLogs.timedate ) ,  @perv_day1) _day
  from userLogs , 
       (select  @row_counter2 :=0) y # here I define the row with 0
       (select @perv_day2 :=0) y # to track rank for each row 
  where userLogs.action ='logout'
  group by user # here i group each user
现在我有了数据,我想加入他们,这样我可以找到时间的差异,但是需要什么样的条件才能这样做

select TIMESTAMPDIFF(MINUTE, logIn.timedate, logOut.timeDate) as howLongUserStaysInMinutes
from logIn
left join logOut on (logOut.user =  logIn.user) # same user
              and DAY( logIn.timedate )  =  DAY( logOut.timedate ) # action at the same day
              and logIn.rowRankedByDay= logOut.rowRankedByDay # login and logout actions rows
              and ( logIn.timedate <= logOut.timedate ||   logOut.timedate is null) # login was before logout or user did not logout

抱歉,如果这里有更多代码;我希望这对你有帮助

您已经尝试过的查询是什么?这是我自己已经尝试过的,但是有很多问题。明天我会试试你的代码,也许比我的更干净。谢谢。嗯,我很难理解你所有的代码,但明天我会尝试,如果它能工作,我会让你知道。谢谢好的,在这个查询中有一个小问题我不知道如何处理,结果是第一次登录(例如2016-01-15 11:39:35)和第一次注销(例如2016-01-22 11:25:33)之间存在差异。只有当它们在同一天时,我才需要计算差异。我甚至每天都可以做这个查询。有什么帮助吗?另一个问题,如果我在同一天有2个登录和1个注销,查询必须取最大值,并放弃另一个。例如:2016-01-25 11:02:54->登录| 2016-01-25 14:08:49->登录| 2016-01-25 14:09:19->注销我需要第二次登录和注销之间的差异谢谢。谢谢,但现在的问题是:我如何将所有代码放在一个查询中?我无法创建视图,因为它包含变量。我分别进行了3次查询,结果是N行为NULL。问题:有一种方法我可以给你发送真实数据库的表吗?谢谢确定找到了错误,在注销查询rankedbyday总是空的,现在我搜索原因。
  select id, 
         timedate as timedate, # here you can use max() to get max login in day
         user,
         action, # action will be logout since it specified at where clause
         @row_counter2 := if(@perv_day2 <> DAY( userLogs.timedate ) , 1 , @row_counter1 +1) rankedByDay,
         @perv_day1 := if(@perv_day1 <> DAY( userLogs.timedate ) , DAY( userLogs.timedate ) ,  @perv_day1) _day
  from userLogs , 
       (select  @row_counter2 :=0) y # here I define the row with 0
       (select @perv_day2 :=0) y # to track rank for each row 
  where userLogs.action ='logout'
  group by user # here i group each user
id  timedate            user    action  rowRankedByDay
2   2010-01-01 12:01:01 AB991   logout  1
4   2010-01-01 18:01:01 AB991   logout  2
6   2010-01-01 10:01:01 ZM991   logout  3
8   2010-01-02 18:01:01 AB991   logout  1
select TIMESTAMPDIFF(MINUTE, logIn.timedate, logOut.timeDate) as howLongUserStaysInMinutes
from logIn
left join logOut on (logOut.user =  logIn.user) # same user
              and DAY( logIn.timedate )  =  DAY( logOut.timedate ) # action at the same day
              and logIn.rowRankedByDay= logOut.rowRankedByDay # login and logout actions rows
              and ( logIn.timedate <= logOut.timedate ||   logOut.timedate is null) # login was before logout or user did not logout