SQL 发现日期之间没有活动

Posted

技术标签:

【中文标题】SQL 发现日期之间没有活动【英文标题】:SQL finding no activity between dates 【发布时间】:2017-04-22 05:19:59 【问题描述】:

我试图从使用 Postgres 的 EmployeeActivity 表中找出公司有多少天没有任何加入员工或裁员的活动。 Null 是指仍在公司内部从事活动的人,而 DateLeave 是指离开公司或不再工作的人。

DateJoined   DateLeave     Name
................................
2012-06-20   NULL          Terrence
2012-06-21   2013-06-23    Mady
2010-06-20   2012-06-24    Greg
2013-06-20   NULL          Matt

我的试验是

select EXTRACT(DAY FROM MAX(EmployeeActivity.DateJoined) - MIN(EmployeeActivity.DateLeave) 

From EmployeeActivity

WHERE EmployeeActivity.DateLeave IS 'NULL'

但是它显示了错误的值,尤其是对于较长的表

输出预期: 我对此输出的期望是查询公司在分配或解雇员工方面没有活动的最长天数。

【问题讨论】:

根据提供的数据集,期望的结果集是什么样的? @Strawberry 感谢反馈我已经重写了问题 您向我们展示了您已经尝试过的内容,但根据您显示的数据,您没有看到您期望的输出结果。 【参考方案1】:

如果我理解正确,以下应该满足您的需求:

    SELECT
        ActivityDate,
        lag(ActivityDate) over (ORDER BY ActivityDate) as PreviousActivityDate,
        Date_Part('day',ActivityDate - lag(ActivityDate) over (ORDER BY ActivityDate)) as Difference
    FROM
        (
        select DateJoined as ActivityDate from EmployeeActivity
        union
        select coalesce(DateLeave,now()) from EmployeeActivity 
        ) AllActivityDates
    ORDER BY Difference DESC
    LIMIT 1 OFFSET 1

OFFSET 1 的原因是因为最早的DateJoined 没有前一行,而那个到顶部,我们只是跳过它。

【讨论】:

感谢回复这正是我所需要的,coalesce 是否在“dateleave”和“now”之间进行选择? @史蒂夫洛弗尔 coalesce 输出提供的第一个参数不是null,因此对于没有休假日期的人,它会给出当前日期(和时间)。 谢谢,对于 PreviousActivityDate 和 Difference,我可以知道为什么这样写的查询。我认为这是最后一个问题,因为我在网上冲浪后还没有理解这两个功能@steve-lovell 其中重要的部分是lag 函数。这就是所谓的window function,它使查询能够以有用的方式跨行查看。然而,要使这些工作,代码必须知道如何排序(有时如何分组)数据,这就是 OVER (ORDER BY ...) 的用武之地。窗口函数非常有用,当然值得学习。 也就是说,您通常可以通过其他方式实现相同的目标,但通常会涉及至少一个额外的子查询,并且通常会使您的代码更难理解。

以上是关于SQL 发现日期之间没有活动的主要内容,如果未能解决你的问题,请参考以下文章

SSAS 获取两个日期之间的活动记录数

MySQL活动期间订单满600元并且在活动日期之前超过30天没有下过单_20161030

java 在活动之间传递日期时间戳

计算 T-SQL 中两个日期范围之间的交叉点数

Oracle SQL 多列与单个范围/图例对齐

参考日期前后的 sql 持续时间