使用betwenn join 求 dept_emp 表中计算每个部门每个月的在职人数

如题所示 ,下面是表结构

[email protected]>[employees]>desc dept_emp;
+-----------+---------+------+-----+---------+-------+
| Field     | Type    | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| emp_no    | int(11) | NO   | PRI | NULL    |       |
| dept_no   | char(4) | NO   | PRI | NULL    |       |
| from_date | date    | NO   |     | NULL    |       |
| to_date   | date    | NO   |     | NULL    |       |
+-----------+---------+------+-----+---------+-------+
4 rows in set (0.00 sec)

从上面的表结构中 求出满足以下条件
从1985-01-01 到1985-02-28 部门每个部门每天的在职人数

我们想求出满足上面的人 ,from_date 必须小于 2018-02-08 而to_date 必须大于等于 2018-01-01

select dept_no ,  emp_no ,d.from_date,d.to_date  from dept_emp d
where d.from_date <= '1985-02-08'
and d.to_date >= '1985-01-01'


从查询结果中   可以看出 
| d008    | 429002 | 1985-02-20 | 9999-01-01 |

如上图所示 429002 在2-20进入部门d008 现在还在职 就一行数据
我们都知道 聚合函数是对表的行进行计算的 如果想用聚合函数 我们就得复制

如下才行

| d008 | 429002 | 1985-02-20 | 9999-01-01 |
| d008 | 429002 | 1985-02-21 | 9999-01-01 |
| d008 | 429002 | 1985-02-22 | 9999-01-01 |

这样我们 才计算出 20号一天 ,21号一天 22号1天 但现实就是一行数据
这时候 我们需要一个特殊的表!

create table t_time (
id int primary key  auto_increment ,
yymmdd date
)

 
insert into t_time(yymmdd) values('1985-01-01');

 

insert into t_time(yymmdd)
select adddate('1985-01-01',INTERVAL rn day)
from (
select @a:=@a+1 rn from (select * from dept_emp limit 10000) a ,(select @a:=0) b
)c

通过上面的脚本 可以创建一个表 包含从85-01-01到12年的日期!

select dept_no,t.yymmdd ,  emp_no ,d.from_date, d.to_date from dept_emp d , t_time t
where d.from_date <= t.yymmdd
and d.to_date >= t.yymmdd
and t.yymmdd <='1985-02-28'
order by 1 ,3 ,2

| d009    | 1985-02-28 | 489879 | 1985-02-07 | 9999-01-01 |
| d009    | 1985-02-18 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-19 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-20 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-21 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-22 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-23 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-24 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-25 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-26 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-27 | 499222 | 1985-02-18 | 1996-07-07 |
| d009    | 1985-02-28 | 499222 | 1985-02-18 | 1996-07-07 |
+---------+------------+--------+------------+------------+

这样 我们就很好的进行了复制

然后运行如下! 就可以求出 每个部门每个月的在职人数

select dept_no,date_format(t.yymmdd,'%Y%m') , count(distinct emp_no)  from dept_emp d , t_time t
where d.from_date <= t.yymmdd
and d.to_date >= t.yymmdd
and t.yymmdd <='1985-02-28'
group by dept_no,date_format(t.yymmdd,'%Y%m')


+---------+------------------------------+------------------------+
| dept_no | date_format(t.yymmdd,'%Y%m') | count(distinct emp_no) |
+---------+------------------------------+------------------------+
| d001    | 198501                       |                      1 |
| d001    | 198502                       |                     86 |
| d002    | 198501                       |                      2 |
| d002    | 198502                       |                     83 |
| d003    | 198501                       |                      1 |
| d003    | 198502                       |                     76 |
| d004    | 198501                       |                      1 |
| d004    | 198502                       |                    335 |
| d005    | 198501                       |                      1 |
| d005    | 198502                       |                    450 |
| d006    | 198501                       |                      1 |
| d006    | 198502                       |                     70 |
| d007    | 198501                       |                      1 |
| d007    | 198502                       |                    235 |
| d008    | 198501                       |                      1 |
| d008    | 198502                       |                     93 |
| d009    | 198501                       |                      1 |
| d009    | 198502                       |                     92 |
+---------+------------------------------+------------------------+

测试

select count(*) from dept_emp where  from_date<='1985-02-28'  
and to_date>='1985-02-01'  and dept_no = 'd008'

+----------+
| count(*) |
+----------+
|       93 |
+----------+


select dept_no,date_format(t.yymmdd,'%Y%m') , count(distinct emp_no)  from dept_emp d , t_time t
where d.from_date <= t.yymmdd
and d.to_date >= t.yymmdd
and t.yymmdd <='1985-02-28'
and dept_no = 'd008'
group by dept_no,date_format(t.yymmdd,'%Y%m')


---------+------------------------------+------------------------+
| dept_no | date_format(t.yymmdd,'%Y%m') | count(distinct emp_no) |
+---------+------------------------------+------------------------+
| d008    | 198501                       |                      1 |
| d008    | 198502                       |                     93 |
+---------+------------------------------+------------------------+

从结果上可以看出 我们计算的是正确的!

猜你喜欢

转载自blog.csdn.net/qidan3500/article/details/84058679