如何为行中的多个集合计算存储过程中两个日期之间的差异

Posted

技术标签:

【中文标题】如何为行中的多个集合计算存储过程中两个日期之间的差异【英文标题】:How to calculate the difference between two dates in stored procedure for multiple sets in rows 【发布时间】:2020-04-17 09:14:31 【问题描述】:

我有一个这样的数据表

id  typeid      date
12  exited      01-06-2017    
1   approved    05-06-2017
7   attended    08-06-2017
9   admitted    10-06-2017
45  approved    12-06-2017
67  admitted    16-06-2017 

我想要的答案是这样的:

difference(days)
5 
4 

我想计算 approvedadmitted 之间的 date 差异(无论它们在哪里,所以我认为我们必须使用循环语句) .我想在 MySql(版本:5.6)中编写一个存储过程,它以任何形式返回结果(可能是具有这些结果的表)。

【问题讨论】:

【参考方案1】:

这实际上是窗口函数非常适合的问题,但由于您使用的是 5.6 版,所以这是不可能的。这是执行此操作的一种方法:

SELECT
    DATEDIFF(
        (SELECT t2.date FROM yourTable t2
         WHERE t2.typeid = 'admitted' AND t2.date > t1.date
         ORDER BY t2.date LIMIT 1),
        t1.date) AS difference
FROM yourTable t1
WHERE
    typeid = 'approved'
ORDER BY
    date;

上述查询中的逻辑是我们只限制批准类型的记录。对于每个这样的记录,使用一个相关的子查询,然后我们提前寻找时间并找到允许类型的最近记录。然后,我们计算这两个日期之间的差异。

检查下面的工作演示链接。

Demo

【讨论】:

【参考方案2】:

如果您关心性能,您可以为每一行分配一个值,即“录取”的累积数量。然后使用它进行聚合:

select max(case when typeid = 'approved' then date end) as approved_date,
       max(case when typeid = 'admitted' then date end) as admitted_date,
       datediff(max(case when typeid = 'admitted' then date end),
                max(case when typeid = 'approved' then date end)
               ) as diff
from (select t.*,
             (@cnt := @cnt + (typeid = 'approved')) as grp
      from (select t.* from t order by date) t cross join
           (select @cnt := 0) params
     ) t
group by grp;

这可以利用(date) 上的索引来分配grp。然后它只需要做一个group by

随着数据规模的增长,使用相关子查询的成本会变得非常高。所以对于更大的数据,这应该会更有效率。

在任何一种情况下,使用窗口函数(在 mysql 8+ 中可用)都是首选的解决方案。

【讨论】:

以上是关于如何为行中的多个集合计算存储过程中两个日期之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何为存储过程编写 Hibernate 映射文件?

如果我有重复的日期,如何用 pandas 中两个日期之间计算的值填充一列?

需要 mongodb 查询来检查日期是不是在存储在集合文档中的两个日期之间[重复]

如何通过Period类计算两个日期的差?

java 中 判断两个日期月份的差,后面没有时分秒.比如2013-07-03与2013-09-03 返回值为2

如何为 Python 中唯一的项目测试多个集合?