MySQL在没有活动的情况下获得最长的间隙

Posted

技术标签:

【中文标题】MySQL在没有活动的情况下获得最长的间隙【英文标题】:MySQL get longest gap without activity 【发布时间】:2014-02-24 17:30:31 【问题描述】:

我有这张桌子

CREATE TABLE 员工 (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(32),
  `姓氏` varchar(32),
  `dateEnrollment` 日期,
  `dateCompletion` 日期,
  主键(`id`)
);

插入员工(`firstname`、`surname`、`dateEnrollment`、`dateCompletion`)值
('演示', '演示', '2010-01-13', '2010-02-13'),
('Jone', 'Borek', '2010-02-14', '2011-03-13'),
(“丹尼斯”、“科西”、“2010-02-15”、“2010-06-13”);

我需要 SQL 查询来返回我最长的没有任何活动的时间段。例如:Jone Borek 完成 2011 年 3 月 13 日至 Denis Koszi 完成 2010 年 6 月 13 日 - 在此期间公司没有活动......我怎样才能实现它?非常感谢您的帮助

【问题讨论】:

【参考方案1】:

以下任何一种都可以, (我更喜欢后者):

SELECT 
MAX(DATEDIFF(
(SELECT MIN(s2.dateCompletion) 
    FROM staff s2 
    WHERE s2.dateCompletion >= s.dateCompletion AND s2.id != s.id)
, dateCompletion))
from staff s;

在上面的例子中,对于每条记录,你找到下一个完成的项目,做一个 datediff,然后取最大值。

在下面的示例中,我使用连接来做同样的事情。如果你的数据集真的很大,你最好创建一个临时表并摆脱派生表。

SELECT
MAX(DATEDIFF(s2.dateCompletion, s.dateCompletion))
FROM staff s
JOIN staff s2 ON s2.dateCompletion = (SELECT MIN(s3.dateCompletion) 
    FROM staff s3 
    WHERE s3.dateCompletion >= s.dateCompletion
      AND s3.id != s.id)

另外,当您测量最长不活动时间时,您是否还想包括 MAX(dateCompletion) 和 CURDATE() 之间的日期差异,然后使用以下内容:

SELECT
MAX(DATEDIFF(COALESCE(s2.dateCompletion, CURDATE()), s.dateCompletion))
FROM staff s
JOIN staff s2 ON s2.dateCompletion = (SELECT MIN(s3.dateCompletion) 
    FROM staff s3 
    WHERE s3.dateCompletion >= s.dateCompletion
      AND s3.id != s.id)

【讨论】:

【参考方案2】:

试试:

SELECT s1.id id1,
       s1.firstname firstname1,
       s1.surname surname1,
       s1.`dateCompletion` dateCompletion1,
       s2.id id2,
       s2.firstname firstname2,
       s2.surname surname2,
       s2.`dateCompletion` dateCompletion2,
       datediff( s1.`dateCompletion`, s2.`dateCompletion` )
FROM staff s1
JOIN staff s2
ON s1.`dateCompletion` = (
        SELECT min(dateCompletion)
        FROM staff s3
        WHERE s3.dateCompletion > s2.`dateCompletion`
  ) 
ORDER BY datediff( s2.`dateCompletion`, s1.`dateCompletion` )
LIMIT 1

演示:http://sqlfiddle.com/#!2/c1e939/8

【讨论】:

【参考方案3】:
select x.firstname as firstname1,x.surname as surname1,y.firstname as firstname2,y.surname as surname2,MIN(ABS(DATEDIFF(x.dateEnrollment,x.dateCompletion)-DATEDIFF(y.dateEnrollment,y.dateCompletion))) AS parameter
    from staff x join staff y on 
    x.dateEnrollment <= y.dateCompletion and y.dateEnrollment <= x.dateCompletion and x.firstname!=y.firstname and x.surname!=y.surname

这将提供两个人的详细信息以及参数值,如果这就是您的问题的意思,该参数值应该是两个人停留时间最长的最小值。 如果需要,您还可以在结果中添加日期。

还有一种更快的方法是将它与 having 子句一起使用:

 select x.firstname as firstname1,x.surname as surname1,y.firstname as firstname2,y.surname as surname2
    from staff x join staff y on 
    x.dateEnrollment <= y.dateCompletion and y.dateEnrollment <= x.dateCompletion and x.firstname!=y.firstname and x.surname!=y.surname HAVING MIN(ABS(DATEDIFF(x.dateEnrollment,x.dateCompletion)-DATEDIFF(y.dateEnrollment,y.dateCompletion)))

希望对你有帮助!!

【讨论】:

以上是关于MySQL在没有活动的情况下获得最长的间隙的主要内容,如果未能解决你的问题,请参考以下文章

Python:在整数的二进制表示中查找最长的二进制间隙

如何优化 sql 查询以避免在没有 php.ini 或设置时间限制的情况下执行最长时间 [关闭]

在JavaScript中查找整数的二进制表示中最长的零序列?

有没有更好的方法(最快)来获得最长的公共文件夹路径?

MySQL - 获取最长字符串匹配的记录

在熊猫队中连续几周获得最长连胜纪录