【问题标题】:MySQL Date difference between two rows两行之间的MySQL日期差异
【发布时间】:2014-08-22 23:09:36
【问题描述】:

我有一个 TABLE 列:USER_ID,TIMESTAMPACTION

每一行都告诉我哪个用户在某个时间戳执行了什么操作。

示例:

  • Alice 于 2014-06-12 16:37:46 开始申请
  • Alice 于 2014-06-12 17:48:55 停止申请

我想要一个用户列表,其中包含他们启动应用程序的第一行和他们关闭应用程序的最后一行之间的时间差。

这是我的尝试:

    SELECT USER_ID,DATEDIFF(
(SELECT timestamp FROM MOBILE_LOG WHERE ACTION="START_APP" AND USER_ID="Alice"  order by TIMESTAMP LIMIT 1),
(SELECT timestamp FROM MOBILE_LOG WHERE ACTION ="CLOSE_APP" AND USER_ID="Alice"  order by TIMESTAMP LIMIT 1)
) AS Duration FROM MOBILE_LOG AS t WHERE USER_ID="Alice";

我要求两个 SELECT 查询之间的 DATEDIFF,但我只得到一个 Alice 的列表,其中 -2 作为 Duration。

我走对了吗?

【问题讨论】:

  • 您希望如何查看差异?在毫秒或几小时内你有一个面具(提供它,比如:`YYYY-MM-DD HH:MI:SS`)?
  • 一个面具会很棒! DD HH:MM(40 天 3 小时 4 分钟)

标签: mysql sql row datediff


【解决方案1】:
SELECT user_id, start_time, close_time, DATEDIFF(close_time, start_time) duration
FROM
   (SELECT MIN(timestamp) start_time, user_id FROM MOBILE_LOG WHERE action="START_APP" GROUP BY user_id) start_action
  JOIN
   (SELECT MAX(timestamp) close_time, user_id FROM MOBILE_LOG WHERE ACTION ="CLOSE_APP" GROUP BY user_id) close_action
  USING (user_id)
WHERE USER_ID="Alice";

您制作了两个“表格”,每个用户的最早开始时间和每个用户的最晚关闭时间。然后加入它们,使同一用户的操作在一起。

现在您已经完成了所有设置,您可以轻松地在它们之间减去。

【讨论】:

    【解决方案2】:

    我认为您应该按 USER_ID 对该表进行分组,并为每个用户找到“START_APP”的最短日期和“CLOSE_APP”的最长日期。此外,您应该在DATEDIFF 中先使用 CLOSE_APP 时间,然后再使用 START_APP 时间,在这种情况下,您将获得正值结果

    SELECT USER_ID,
           DATEDIFF(MAX(CASE WHEN ACTION="CLOSE_APP" THEN timestamp END),
                    MIN(CASE WHEN ACTION="START_APP" THEN timestamp END)
                   ) AS Duration 
    FROM MOBILE_LOG AS t 
    GROUP BY USER_ID
    

    SQLFiddle demo

    【讨论】:

    • 那不行,开始和结束在不同的行。
    • 我收回了。它会起作用的——最后我完全错过了GROUP BY。很聪明!赞成教我一些新东西。但是 - 这会很慢,因为你不能索引任何东西,所以实际上不要这样做,使用我的方法。
    • 这似乎可行,我只是想删除新创建的 Duration 列上的 NULL 值,但一个简单的 WHERE 不起作用:(
    • @Mark 使用HAVING 而不是WHERE,因为条件发生在GROUP BY 之后。但我建议你使用我的代码,因为它会运行得更快(除非它的行数不多并且速度无关紧要)。
    • @Ariel 您的两个解决方案都可以在 0.06 秒内顺利运行(我有一个小数据库)我真的不知道该接受哪个答案 :-)
    【解决方案3】:

    你有 int 值是因为你使用函数 DATEDIFF,它显示两个日期之间的天数,如果你想知道日期之间的小时数和分钟数和秒数,你必须使用 TIMEDIFF 试试这个:

    select t1.USER_ID, TIMEDIFF(t2.timestamp, t1.timestamp)
      from MOBILE_LOG  t1, MOBILE_LOG  t2
     where (t1.action,t1.timestamp) in (select action, max(timestamp) from MOBILE_LOG t where t.ACTION = "START_APP" group by USER_ID)
       and (t1.action,t1.timestamp) in (select action, max(timestamp), max(id) from MOBILE_LOG t where t.ACTION = "CLOSE_APP" group by USER_ID)
       and t1.USER_ID = t2.USER_ID
    

    它将显示所有用户的两个最新日期(开始日期、结束日期)之间的差异。

    P.S:对不起,我写的没有任何数据库,可能有一些错误。如果您对(t1.action,t1.timestamp) in (select...) 有疑问,请将其分成两部分:where t1.action in (select ...) and t1.timestamp in (select ...)

    【讨论】:

    • 他不是这么问的。您应该自行删除您的答案。
    • 他说他想看看小时和分钟的差异,不是吗?
    • 下次发表评论(好吧,一旦你有足够的积分就可以这样做)。您的答案中没有任何代码,只是指向其他地方的链接,stackoverflow 不喜欢这样的答案。
    • 对不起,我不是 SQL 查询专家,您的所有帖子对我来说都很有趣,我正在考虑使用 TIMEDIFF
    • 更改了我的帖子,当我第一次阅读您的问题时,我不明白您需要什么。
    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 2015-11-22
    • 2017-06-13
    • 2011-10-29
    • 1970-01-01
    • 2012-06-10
    • 2014-02-12
    • 2015-09-14
    相关资源
    最近更新 更多