ORACLE SQL - 基于不同日期的查询
ORACLE SQL - query based on different dates
我想知道过去几年我的数据库中有多少员工。所有员工都在一个 table 中(即使是已经离开的员工),这个 table 还包含他们的就业开始和结束日期。
我想要一个这样的table
日期 ------ 成员
01/01/2020 ---- 100
02/01/2020 ---- 99
31/12/2020 ---- 101
我想我可以使用以下 SQL 查询,我在其中创建了所有之前 365 天的列表并计算了员工人数:
SELECT TRUNC (SYSDATE - ROWNUM) dt,
(SELECT COUNT(DISTINCT TLC) FROM CREW_MEMBER
WHERE crew_member.employment_begin_dt <= TRUNC (SYSDATE - ROWNUM)
AND
CREW_MEMBER.EMPLOYMENT_END_DT >= TRUNC(SYSDATE - ROWNUM)
) AANTAL_CREW
FROM DUAL
CONNECT BY ROWNUM < 366
然而,这并没有给我想要的结果,因为我得到的所有日期的值都相同。我认为这是因为内部 select 语句使用它自己的行而不是我的 DUAL table.
中的行
有什么我可以做的吗?
谢谢!
您可以逆透视数据并跟踪“入驻”机组成员和“出局”机组成员。累积总和(和聚合)然后得到每天的总和:
select dte,
sum(inc) as change_on_day,
sum(sum(inc)) over (order by dte) as active_on_day
from ((select cm.employment_begin_dt as dte, 1 as inc
from crew_member cm
) union all
(select cm.employment_end_dt + interval '1' day as dte, -1 as inc
from crew_member cm
where employment_end_dt is not null
)
) e
group by dte
order by dte;
如果您想要每天一行,那么您确实需要生成该范围内的所有日期(除非所有日期都已在 table 中可用,但您没有告知)。为此,我喜欢使用标准递归 CTE。
然后您可以将 table 与 left join
相结合,然后合计:
我会推荐:
with all_dates (dt) as (
select trunc(sysdate) from dual
union all
select dt - 1 from all_dates where dt > trunc(sysdate) - interval '12' month
)
select d.dt, count(distinct cm.employment_begin_dt) cnt
from all_dates d
left join crew_member cm
on cm.employment_begin_dt <= d.dt
and cm.employment_end_dt >= d.dt
group by d.dt
我想知道过去几年我的数据库中有多少员工。所有员工都在一个 table 中(即使是已经离开的员工),这个 table 还包含他们的就业开始和结束日期。
我想要一个这样的table
日期 ------ 成员
01/01/2020 ---- 100
02/01/2020 ---- 99
31/12/2020 ---- 101
我想我可以使用以下 SQL 查询,我在其中创建了所有之前 365 天的列表并计算了员工人数:
SELECT TRUNC (SYSDATE - ROWNUM) dt,
(SELECT COUNT(DISTINCT TLC) FROM CREW_MEMBER
WHERE crew_member.employment_begin_dt <= TRUNC (SYSDATE - ROWNUM)
AND
CREW_MEMBER.EMPLOYMENT_END_DT >= TRUNC(SYSDATE - ROWNUM)
) AANTAL_CREW
FROM DUAL
CONNECT BY ROWNUM < 366
然而,这并没有给我想要的结果,因为我得到的所有日期的值都相同。我认为这是因为内部 select 语句使用它自己的行而不是我的 DUAL table.
中的行有什么我可以做的吗?
谢谢!
您可以逆透视数据并跟踪“入驻”机组成员和“出局”机组成员。累积总和(和聚合)然后得到每天的总和:
select dte,
sum(inc) as change_on_day,
sum(sum(inc)) over (order by dte) as active_on_day
from ((select cm.employment_begin_dt as dte, 1 as inc
from crew_member cm
) union all
(select cm.employment_end_dt + interval '1' day as dte, -1 as inc
from crew_member cm
where employment_end_dt is not null
)
) e
group by dte
order by dte;
如果您想要每天一行,那么您确实需要生成该范围内的所有日期(除非所有日期都已在 table 中可用,但您没有告知)。为此,我喜欢使用标准递归 CTE。
然后您可以将 table 与 left join
相结合,然后合计:
我会推荐:
with all_dates (dt) as (
select trunc(sysdate) from dual
union all
select dt - 1 from all_dates where dt > trunc(sysdate) - interval '12' month
)
select d.dt, count(distinct cm.employment_begin_dt) cnt
from all_dates d
left join crew_member cm
on cm.employment_begin_dt <= d.dt
and cm.employment_end_dt >= d.dt
group by d.dt