【问题标题】:SQL finding no activity between datesSQL 发现日期之间没有活动
【发布时间】: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 感谢反馈我已经重写了问题
  • 您向我们展示了您已经尝试过的内容,但根据您显示的数据,您没有看到您期望的输出结果。

标签: sql postgresql


【解决方案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 ...) 的用武之地。窗口函数非常有用,当然值得学习。
  • 也就是说,您通常可以通过其他方式实现相同的目标,但通常会涉及至少一个额外的子查询,并且通常会使您的代码更难理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多