年度按标准计算

时间:2013-07-30 19:11:40

标签: sql tsql ssis

我正在与人力资源部门合作开展一个项目。 我有一个名为[EEMaster]的表,记录了Active / Termed员工。 它使用缓慢变化的维度从平面文件更新。

在年底,我需要计算活跃员工的数量和被称为员工的数量,然后是年份。

以下是我每年需要返回的数据示例。

             | 2010 | 2011 | 2012 | 2013 |
HistoricalHC | 447  | 419  | 420  | 418  |
NumbTermEmp  | 57   | 67   |  51  | 42   |

我目前将数据连接到excel电子表格,按照分部提供滚动计数。我使用[EEMaster]中的以下列来表示它。

  • ChangeStatus(SCD中的1/0)
  • EmpStatusName(现有员工为“Active”,“Termed Employe”为“已撤销”)
  • HireYear(在数据透视表中设置为All)
  • Term Year(在数据透视表中设置为2013)
  • PONumb(员工编号,我用于计算)

我创建了一个表来输入数据,我将手动将前几年(计数)加载到表中,因为当前开发是滚动数。我想要做的是开发一个SSIS包,它将在2014年1月1日捕获计数,并插入“活跃员工”,“主流员工”和刚刚完成表格的年份。

更新:

我创建了两个查询。一个提供活跃员工人数

SELECT COUNT([PersNo]) AS HistoricalHC
FROM [dbo].[EEMaster]
WHERE [ChangeStatus] = 'Current' AND [EmpStatusName] = 'Active'

它返回

|HistoricHC|
|418       |

另一个按术语年提供术语数量

SELECT COUNT([PersNo]) AS NumbOfTermEE
FROM [dbo].[EEMaster]
WHERE [ChangeStatus] = 'Current' AND [EmpStatusName] = 'Withdrawn' 
AND [TermYear] = '2013'

它返回

|NumbOfTermEE|
|42          |

我需要[TermYear]是动态的。由于这将在每年的1月1日运行。它需要提取前一年的条款数量(不断)。

然后我需要将这两个数字添加到新行中,并计算数据的年份。

|Year|HistoricalHC|NumbOfTermEmp|
|2010|447         |57           |
|2011|419         |67           |
|2012|420         |51           |
|2013|418         |42           |

3 个答案:

答案 0 :(得分:1)

您正在寻找一个案例表达式的语法,该案例表达式执行聚合以为不同的事物添加一些。

Sum(Case when (expression) then 1 end)

您还希望按列显示在列中,以便您可以轻松地进行调整。你提到了动态,但我真的不知道你是否需要在年度逻辑上获得更多动态。如果你想要一个SQL语句进入数据流来生成Excel工作表的输出,我真的没有得到。基本上,如果你只想要一个网格,其中一行是一组条件而另一行是另一组。我会做两个或更多选择的'联合',只要它不是太大它不应该那么难。这是一个简单的自提取示例,其中包含虚拟数据以了解我的意思。

它将在SQL Management Studio 2005及更高版本中运行。

declare @Person Table ( personID int identity, person varchar(8));

insert into @Person values ('Brett'),('Sean'),('Chad'),('Michael'),('Ray'),('Erik'),('Queyn');

declare @Orders table ( OrderID int identity, PersonID int, OrderCnt int, dt Date);

insert into @Orders values (1, 10, '1-7-11'),(1, 12, '2-12-12'),(2, 20, '7-1-13'),(2, 12, '1-5-10'),(3, 20, '6-4-11')
,(3, 12, '2-3-10'),(3, 6, '6-10-10'),(4, 20, '7-10-11'),(5, 20, '1-8-10'),(5, 9, '2-10-11'),
(6, 20, '3-1-11'),(6, 34, '4-6-12'),(7, 20, '5-1-11'),(7, 12, '6-8-12'),(7, 56, '7-25-13')

-- As is just joining sets
select *
from @Person p
    join @Orders o on p.personID = o.PersonID
order by dt

-- Years on the rows
select
    year(o.dt) as Year
,   sum(o.OrderCnt) as Orders
,   count(p.personID) as People
,   count(distinct p.personID) as DistinctPeople
from @Person p
    join @Orders o on p.personID = o.PersonID
group by year(o.dt)

-- Custom grouping on rows and doing the years with pivots for the columns
Select 
    'BulkOrders' as Description
,   sum(case when year(o.dt) = '2010' then OrderCnt end) as [2010Orders]
,   sum(case when year(o.dt) = '2011' then OrderCnt end) as [2011Orders]
,   sum(case when year(o.dt) = '2012' then OrderCnt end) as [2012Orders]
,   sum(case when year(o.dt) = '2013' then OrderCnt end) as [2013Orders]
,   sum(OrderCnt) as Totals
from @Person p
    join @Orders o on p.personID = o.PersonID
union
select
    'OrdersByPerson'
,   Count(case when year(o.dt) = '2010' then p.personID  end) 
,   Count(case when year(o.dt) = '2011' then p.personID end) 
,   Count(case when year(o.dt) = '2012' then p.personID end) 
,   Count(case when year(o.dt) = '2013' then p.personID end) 
,   Count(p.personID)
from @Person p
    join @Orders o on p.personID = o.PersonID
union
select
    'OrdersByPersonDistinct'
,   Count(distinct case when year(o.dt) = '2010' then p.personID  end)
,   Count(distinct case when year(o.dt) = '2011' then p.personID end) 
,   Count(distinct case when year(o.dt) = '2012' then p.personID end) 
,   Count(distinct case when year(o.dt) = '2013' then p.personID end) 
,   Count(distinct p.personID)
from @Person p
    join @Orders o on p.personID = o.PersonID

答案 1 :(得分:0)

这是我提出的解决方案。

我将创建一个SSIS包,它将运行以下存储过程。

    INSERT INTO [dbo].[TORateFY] (Year,HistoricalHC,NumbTermedEmp)
    SELECT  DISTINCT YEAR(GETDATE()) AS [Year],
        SUM(CASE WHEN EmpStatusName = 'Active' THEN 1 ELSE 0 END) AS HistoricalHC,
        SUM(CASE WHEN EmpStatusName = 'Withdrawn' AND TermYear = YEAR(GETDATE()) THEN 1 ELSE 0 END) AS NumbOfTermEE
    FROM    dbo.EEMaster

这将安排在12月31日每年举行。

答案 2 :(得分:0)

更新到我之前的答案:

我在另一个论坛上与一个人合作,他提供了一个优秀的脚本,可以按月为活跃和被称为员工提供正确的计数,而不是等到年底才能获得总体计数。这使得报告更加符合最初手动完成的内容。

MERGE dbo.TORateFY AS tgt
USING (
   SELECT DATENAME(YEAR, GETDATE()) AS [Year],
     SUM(CASE WHEN EmpStatusName = 'Active' THEN 1 ELSE 0 END) AS HistoricalHC,
     SUM(CASE WHEN EmpStatusName = 'Withdrawn' AND TermYear = DATENAME(YEAR,
     GETDATE()) THEN 1 ELSE 0 END) AS NumbOfTermEE
   FROM dbo.EEMaster
   WHERE ChangeStatus = 'Current'
    AND EmpStatusName IN ('Active', 'Withdrawn')
    OR TermYear <= DATENAME(YEAR, GETDATE())
  ) AS src ON src.[Year] = tgt.[Year]
WHEN MATCHED
  THEN UPDATE
    SET tgt.HistoricalHC = src.HistoricalHC,
        tgt.NumbTermedEmp = src.NumbOfTermEE
WHEN NOT MATCHED BY TARGET
THEN INSERT (
             [Year],
             HistoricalHC,
             NumbTermedEmp
             )
VALUES (
         src.[Year],
         src.HistoricalHC,
         src.NumbOfTermEE
             );

我想分享以防其他人遇到类似情况。

感谢大家的意见和建议。