Если у нас есть календарь размер таблицы или даты, запрос, просмотр ... и т. д., это становится намного проще.
/* example Calendar, just Months */
create table dbo.Calendar(
MonthStart date primary key
, MonthEnd date
);
declare @FromDate date = '20000101';
declare @ThruDate date = '20301201';
with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, d as (
select DateValue=convert(date,dateadd(month
, row_number() over (order by (select 1)) -1, @fromdate))
from n as deka
cross join n as hecto
cross join n as kilo
)
insert into dbo.Calendar
select top (datediff(month, @FromDate, @ThruDate)+1)
MonthStart = dateadd(month, datediff(month, 0, DateValue), 0)
, MonthEnd = dateadd(day,-1, dateadd(month, datediff(month, 0, DateValue)+1, 0))
from d
order by DateValue;
запроса с использованием common table expression, а затем sum(case when.. 1 else 0 end)
;with cte as (
select
c.MonthStart
, c.MonthEnd
, e.EmpCode
, e.JoinDate
, e.ResignDate
from dbo.Calendar as c
inner join dbo.EmpMaster as e
on c.MonthEnd >= e.JoinDate
and c.MonthStart <= e.ResignDate
)
select
MonthStart
, MonthEnd
, CurrentEmployees = sum(
case when JoinDate < MonthStart
then 1 else 0 end)
, Joined = sum(
case when JoinDate >= MonthStart and JoinDate <= MonthEnd
then 1 else 0 end)
, Resigned = sum(
case when ResignDate >= MonthStart and ResignDate <= MonthEnd
then 1 else 0 end)
, CurrentStatus = sum(
case when ResignDate > MonthEnd
then 1 else 0 end)
from cte
group by
cte.MonthStart
, cte.MonthEnd
order by cte.MonthStart;
без КТР, и используя вместо count(case when ... then column else null end)
:
select
MonthStart
, MonthEnd
, CurrentEmployees = count (
case when JoinDate < MonthStart
then EmpCode else null end)
, Joined = count (
case when JoinDate >= MonthStart and JoinDate <= MonthEnd
then EmpCode else null end)
, Resigned = count (
case when ResignDate >= MonthStart and ResignDate <= MonthEnd
then EmpCode else null end)
, CurrentStatus = count (
case when ResignDate > MonthEnd
then EmpCode else null end)
from (
select
c.MonthStart
, c.MonthEnd
, e.EmpCode
, e.JoinDate
, e.ResignDate
from dbo.Calendar as c
inner join dbo.EmpMaster as e
on c.MonthEnd >= e.JoinDate
and c.MonthStart <= e.ResignDate
) as cte
group by cte.MonthStart, cte.MonthEnd
order by cte.MonthStart
Каждый возвращает те же результаты: http://rextester.com/AEZTL76069
+------------+------------+------------------+--------+----------+---------------+
| MonthStart | MonthEnd | CurrentEmployees | Joined | Resigned | CurrentStatus |
+------------+------------+------------------+--------+----------+---------------+
| 2010-01-01 | 2010-01-31 | 0 | 3 | 0 | 3 |
| 2010-02-01 | 2010-02-28 | 3 | 1 | 0 | 4 |
| 2010-03-01 | 2010-03-31 | 4 | 2 | 0 | 6 |
| 2010-04-01 | 2010-04-30 | 6 | 1 | 0 | 7 |
| 2010-05-01 | 2010-05-31 | 7 | 2 | 0 | 9 |
| 2010-06-01 | 2010-06-30 | 9 | 1 | 0 | 10 |
| 2010-07-01 | 2010-07-31 | 10 | 1 | 0 | 11 |
| 2010-08-01 | 2010-08-31 | 11 | 2 | 0 | 13 |
| 2010-09-01 | 2010-09-30 | 13 | 6 | 0 | 19 |
| 2010-10-01 | 2010-10-31 | 19 | 2 | 0 | 21 |
| 2010-11-01 | 2010-11-30 | 21 | 1 | 0 | 22 |
| 2010-12-01 | 2010-12-31 | 22 | 0 | 0 | 22 |
+------------+------------+------------------+--------+----------+---------------+
Вариации 'COUNT (случай, когда joindate BETWEEN ...)' – dnoeth
Показать, что вы попробовали и мы можем помочь вам, но ТАК не является услугой написания кода , Также решайте, используете ли вы Oracle или SQL Server. Это совершенно разные продукты. –
Где моя схема? Как мы знаем, как они соотносятся друг с другом? И ваш вопрос слишком специфичен, что не поможет будущим посетителям. –