【问题标题】:how to count timediff for each users mysql如何计算每个用户mysql的timediff
【发布时间】:2020-03-06 10:29:53
【问题描述】:

假设我有这样的数据表

ID  users_Id   createdAt
1   12         '2020-01-01'
2   12         '2020-01-03'
3   12         '2020-01-06'
4   13         '2020-01-02'
5   13         '2020-01-03'  

我如何获得每个交易和每个用户的时间差异,所以结果就像这样

MAX   MIN   AVERAGE    MEDIAN
3     1     3          3 

解释:

  • 从 '2020-01-03' 到 '2020-01-06'(3 天)时,users_id 12 中出现的最大时间差异
  • '2020-01-02' 和 '2020-01-03' 之间的交易时,users_id 13 中 timediff 的最小值发生
  • 平均值为 3(users_Id 12 中 2 天 + users_Id 12 中 3 天 + users_Id 13 中 1 天)/users_id 计数(12 和 13)

【问题讨论】:

  • 添加您尝试的代码以获得预期结果以及您得到了什么。
  • MySQL 版本??
  • 5.7 先生@SalmanA
  • 这个 timediff 对我来说很难,先生,我总是有一个 timediff 的例子,每一行,而不是每个 id,所以我在这里有点困惑@Tushar
  • 你真的需要中位数吗?计算起来比其他列复杂得多。

标签: mysql sql date select


【解决方案1】:

你可以使用这样的东西(不计算中位数):

SELECT MIN(diff) AS `MIN`, MAX(diff) AS `MAX`, SUM(diff) / COUNT(DISTINCT user_id) AS `AVG`
FROM (
  SELECT ID, user_id, DATEDIFF((SELECT t2.createdAt FROM test t2 WHERE t2.user_id = t1.user_id AND t1.createdAt <= t2.createdAt AND t2.id <> t1.id LIMIT 1), t1.createdAt) AS diff
  FROM test t1
  WHERE order_status_id in (4, 5, 6, 8)
) DiffTable
WHERE diff IS NOT NULL

在 MySQL 上计算中位数要复杂得多。但是您可以使用基于on this answer on StackOverflow 的类似内容。如您所见,查询变得非常混乱。 MySQL上没有像SUMAVG这样的函数来获取中位数。

SELECT MIN(DiffTable.diff) AS `MIN`, MAX(DiffTable.diff) AS `MAX`, SUM(DiffTable.diff) / COUNT(DISTINCT user_id) AS `AVG`, MIN(median.diff) AS `MEDIAN`
FROM (
  SELECT ID, user_id, DATEDIFF((SELECT t2.createdAt FROM test t2 WHERE t2.user_id = t1.user_id AND t1.createdAt <= t2.createdAt AND t2.id <> t1.id LIMIT 1), t1.createdAt) AS diff
  FROM test t1
  WHERE order_status_id in (4, 5, 6, 8)
) DiffTable, (
  SELECT m1.diff FROM (
    SELECT ID, user_id, DATEDIFF((SELECT t2.createdAt FROM test t2 WHERE t2.user_id = t1.user_id AND t1.createdAt <= t2.createdAt AND t2.id <> t1.id LIMIT 1), t1.createdAt) AS diff
    FROM test t1
    WHERE order_status_id in (4, 5, 6, 8)
  ) m1, (
    SELECT ID, user_id, DATEDIFF((SELECT t2.createdAt FROM test t2 WHERE t2.user_id = t1.user_id AND t1.createdAt <= t2.createdAt AND t2.id <> t1.id LIMIT 1), t1.createdAt) AS diff
    FROM test t1
    WHERE order_status_id in (4, 5, 6, 8)
  ) m2
  WHERE m1.diff IS NOT NULL AND m2.diff IS NOT NULL
  GROUP BY m1.diff
  HAVING SUM(SIGN(1-SIGN(m1.diff-m2.diff))) = (COUNT(*)+1)/2
) median
WHERE DiffTable.diff IS NOT NULL

demo on dbfiddle.uk

【讨论】:

  • 非常感谢先生,我差点忘了先生,我忘记添加列order_status_id,所以如果order_status_id在(4、5、6、8)中,它会被计算在内。我在哪里可以在 (4, 5, 6, 8) 中添加 order_status_id,是在“从测试 t1”之后还是在“差异不为空”之后?
【解决方案2】:

在 MySQL created_at。这将为您提供除中位数之外的所有列:

select
    max(diff) max_diff,
    min(diff) min_diff,
    avg(diff) avg_diff
from (
    select
        t.*,
        datediff(
            created_at, 
            (select max(t1.created_at) from mytable t1 where t1.user_id = t.user_id and t1.created_at < t.created_at) 
        ) diff
    from mytable t
) t

【讨论】:

  • 谢谢先生,但我认为这个查询有点错误,因为您没有定义该 t1 表,而 mysql 无法读取该表
  • 非常感谢先生,我差点忘了先生,我忘记添加列order_status_id,所以如果order_status_id在(4、5、6、8)中,它会被计算在内。我在哪里可以在(4、5、6、8)中添加 order_status_id?是在“t1.createdAt
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 2017-02-16
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
相关资源
最近更新 更多