4

我过去有书面查询,按日期(雇用,终止等)给我计数如下:

SELECT per.date_start AS "Date",
  COUNT(peo.EMPLOYEE_NUMBER) AS "Hires"

FROM hr.per_all_people_f peo,
  hr.per_periods_of_service per

WHERE per.date_start BETWEEN peo.effective_start_date AND peo.EFFECTIVE_END_DATE

AND per.date_start BETWEEN :PerStart AND :PerEnd

AND per.person_id = peo.person_id

GROUP BY per.date_start

我现在正在寻找按日期创建活跃员工的计数,但是我不确定如何确定查询的日期,因为我使用范围来确定活跃员工:

SELECT COUNT(peo.EMPLOYEE_NUMBER) AS "CT"

FROM hr.per_all_people_f peo

WHERE peo.current_employee_flag = 'Y'

and TRUNC(sysdate) BETWEEN peo.effective_start_date AND peo.EFFECTIVE_END_DATE
4

4 回答 4

2

这是一个简单的入门方法。这适用于数据中的所有生效日期和结束日期:

select thedate,
       SUM(num) over (order by thedate) as numActives
from ((select effective_start_date as thedate, 1 as num from hr.per_periods_of_service) union all
      (select effective_end_date as thedate, -1 as num from hr.per_periods_of_service)
     ) dates

它的工作原理是为每个开始添加一个人,为每个结束减去一个人(通过num)并进行累积和。这可能有重复的日期,因此您还可以进行聚合以消除这些重复:

select thedate, max(numActives)
from (select thedate,
             SUM(num) over (order by thedate) as numActives
      from ((select effective_start_date as thedate, 1 as num from hr.per_periods_of_service) union all
            (select effective_end_date as thedate, -1 as num from hr.per_periods_of_service)
           ) dates
     ) t
group by thedate;

如果您真的想要所有日期,那么最好从日历表开始,并在原始查询上使用一个简单的变体:

select c.thedate, count(*) as NumActives
from calendar c left outer join
     hr.per_periods_of_service pos
     on c.thedate between pos.effective_start_date and pos.effective_end_date
group by c.thedate;
于 2013-05-21T18:19:50.723 回答
0

如果要计算在整个输入日期范围内活跃的所有员工

SELECT COUNT(peo.EMPLOYEE_NUMBER) AS "CT"
FROM hr.per_all_people_f peo
WHERE peo.[EFFECTIVE_START_DATE] <= :StartDate   
AND  (peo.[EFFECTIVE_END_DATE] IS NULL OR peo.[EFFECTIVE_END_DATE] >= :EndDate)  
于 2013-05-23T03:34:18.447 回答
0

这是我的示例,基于Gordon Linoff的回答,稍作修改,因为在 SUBSTRACT 表中,所有记录都以 -1 出现在 NUM 中,即使 END DATE = NULL 中没有日期也是如此。

use AdventureWorksDW2012  --using in MS SSMS for choosing DATABASE to work with
                          -- and may be not work in other platforms

select
    t.thedate
    ,max(t.numActives) AS "Total Active Employees"
from (
        select
            dates.thedate
            ,SUM(dates.num) over (order by dates.thedate) as numActives
        from
            (
                (
                select
                    StartDate as thedate
                    ,1 as num
                from DimEmployee
                )
                    union all
                        (
                        select
                            EndDate as thedate
                            ,-1 as num
                        from DimEmployee
                        where EndDate IS NOT NULL
                        )
            ) AS dates
     ) AS t
group by thedate
ORDER BY thedate

为我工作,希望它会帮助别人

于 2016-04-18T21:22:09.840 回答
0

我能够通过以下方式获得我正在寻找的结果:

--Active Team Members by Date
SELECT "a_date",
  COUNT(peo.EMPLOYEE_NUMBER) AS "CT"
FROM hr.per_all_people_f peo,
  (SELECT DATE '2012-04-01'-1 + LEVEL AS "a_date"
  FROM dual
    CONNECT BY LEVEL <= DATE '2012-04-30'+2 - DATE '2012-04-01'-1
  )
WHERE peo.current_employee_flag = 'Y'
AND "a_date" BETWEEN peo.effective_start_date AND peo.EFFECTIVE_END_DATE
GROUP BY "a_date"
ORDER BY "a_date"
于 2017-03-24T21:29:23.860 回答