如果我們有一個日曆表或日期維度,查詢,查看...等,這變得更簡單。
/* 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;
沒有CTE,以及使用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
每返回相同的結果:COUNT的`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 |
+------------+------------+------------------+--------+----------+---------------+
變化(CASE WHEN joindate BETWEEN ...)' – dnoeth
顯示你已經嘗試了,我們可以幫助你從那裏,但何嘗不是一個代碼編寫服務。另外決定你是否使用Oracle或SQL Server。這些是完全不同的產品。 –
你的模式在哪裏?我們如何知道它們是如何相互關聯的呢?而且你的問題太具體,不利於未來的訪問者。 – 2017-02-18 15:15:14