0

我有一个表(TABLE1),列出了所有员工及其部门 ID、他们开始的日期和终止的日期(NULL 表示他们是当前员工)。

我想要一个结果集 (TABLE2) ,其中每一行代表自第一位员工开始工作以来的一天(在下面的示例表中,该日期是 20090101 ),直到今天。(日期字段)。我想按 DeptID 对员工进行分组,并计算 TABLE2 每一行的员工总数。

我该如何查询?感谢您的帮助,提前。

表格1

DeptID     EmployeeID   StartDate   EndDate
--------------------------------------------
001        123           20100101   20120101   
001        124           20090101   NULL
001        234           20110101   20120101

表2

DeptID       Date      EmployeeCount
-----------------------------------
001          20090101     1
001          20090102     1
...          ...          1
001          20100101     2
001          20100102     2
...          ...          2
001          20110101     3
001          20110102     3
...          ...          3
001          20120101     1
001          20120102     1
001          20120103     1
...          ...          1
4

2 回答 2

3

如果您有date查找表,这将起作用。您将需要指定部门 ID。看到它在行动

询问

SELECT d.dt, SUM(e.ecount) AS RunningTotal 
FROM dates d
INNER JOIN
  (SELECT b.dt, 
    CASE
      WHEN c.ecount IS NULL THEN 0
      ELSE c.ecount
    END AS ecount
  FROM dates b 
  LEFT JOIN
    (SELECT a.DeptID, a.dt, SUM([count]) AS ecount
    FROM
       (SELECT DeptID, EmployeeID, 1 AS [count], StartDate AS dt FROM TABLE1
        UNION ALL
        SELECT DeptID, EmployeeID, 
          CASE
            WHEN EndDate IS NOT NULL THEN -1
            ELSE 0
          END AS [count], EndDate AS dt FROM TABLE1) a
    WHERE a.dt IS NOT NULL AND DeptID = 1
    GROUP BY a.DeptID, a.dt) c ON c.dt = b.dt) e ON e.dt <= d.dt
GROUP BY d.dt

结果

| DT | 运行总计 |
-----------------------------------------
| 2009-01-01 | 1 |
| 2009-02-01 | 1 |
| 2009-03-01 | 1 |
| 2009-04-01 | 1 |
| 2009-05-01 | 1 |
| 2009-06-01 | 1 |
| 2009-07-01 | 1 |
| 2009-08-01 | 1 |
| 2009-09-01 | 1 |
| 2009-10-01 | 1 |
| 2009-11-01 | 1 |
| 2009-12-01 | 1 |
| 2010-01-01 | 2 |
| 2010-02-01 | 2 |
| 2010-03-01 | 2 |
| 2010-04-01 | 2 |
| 2010-05-01 | 2 |
| 2010-06-01 | 2 |
| 2010-07-01 | 2 |
| 2010-08-01 | 2 |
| 2010-09-01 | 2 |
| 2010-10-01 | 2 |
| 2010-11-01 | 2 |
| 2010-12-01 | 2 |
| 2011-01-01 | 3 |
| 2011-02-01 | 3 |
| 2011-03-01 | 3 |
| 2011-04-01 | 3 |
| 2011-05-01 | 3 |
| 2011-06-01 | 3 |
| 2011-07-01 | 3 |
| 2011-08-01 | 3 |
| 2011-09-01 | 3 |
| 2011-10-01 | 3 |
| 2011-11-01 | 3 |
| 2011-12-01 | 3 |
| 2012-01-01 | 1 |

架构

CREATE TABLE TABLE1 (
  DeptID tinyint,
  EmployeeID tinyint,
  StartDate date,
  EndDate date)

INSERT INTO TABLE1 VALUES 
(1, 123, '2010-01-01', '2012-01-01'),
(1, 124, '2009-01-01', NULL),
(1, 234, '2011-01-01', '2012-01-01')

CREATE TABLE dates (
  dt date)

INSERT INTO dates VALUES 
('2009-01-01'), ('2009-02-01'), ('2009-03-01'), ('2009-04-01'), ('2009-05-01'), 
('2009-06-01'), ('2009-07-01'), ('2009-08-01'), ('2009-09-01'), ('2009-10-01'), 
('2009-11-01'), ('2009-12-01'), ('2010-01-01'), ('2010-02-01'), ('2010-03-01'), 
('2010-04-01'), ('2010-05-01'), ('2010-06-01'), ('2010-07-01'), ('2010-08-01'), 
('2010-09-01'), ('2010-10-01'), ('2010-11-01'), ('2010-12-01'), ('2011-01-01'), 
('2011-02-01'), ('2011-03-01'), ('2011-04-01'), ('2011-05-01'), ('2011-06-01'), 
('2011-07-01'), ('2011-08-01'), ('2011-09-01'), ('2011-10-01'), ('2011-11-01'), 
('2011-12-01'), ('2012-01-01')
于 2012-09-17T18:47:59.720 回答
1

你需要这些方面的东西。

SELECT  *
      , ( SELECT    COUNT(EmployeeID) AS EmployeeCount 
          FROM      TABLE1 AS f
          WHERE     t.[Date] BETWEEN f.BeginDate AND f.EndDate
        )
FROM    ( SELECT    DeptID
                  , BeginDate AS [Date]
          FROM      TABLE1
          UNION
          SELECT    DeptID
                  , EndDate AS [Date]
          FROM      TABLE1
        ) AS t

编辑,因为 OP 澄清说他希望这里的所有日期都是更新的解决方案,如果他的工作在那个日期结束,我已经从计数中排除了一个员工。但是如果你想在下面的解决方案中包含t.[Date] < f.EndDate 更改t.[Date] <= f.EndDate。另外,我假设NULLEndDate 中的值意味着员工仍然为部门工作。

DECLARE @StartDate DATE = (SELECT MIN(StartDate) FROM Table1)
       ,@EndDate DATE = (SELECT MAX(EndDate) FROM Table1)

;WITH CTE AS 
(
SELECT DISTINCT DeptID,@StartDate AS [Date] FROM Table1
UNION ALL
SELECT c.DeptID, DATEADD(dd,1,c.[Date]) AS [Date] FROM CTE AS c
WHERE c.[Date]<=@EndDate
)
SELECT  * ,
        EmployeeCount=( SELECT    COUNT(EmployeeID) 
          FROM      TABLE1 AS f
          WHERE     f.DeptID=t.DeptID AND  t.[Date] >= f.StartDate
                    AND ( t.[Date] < f.EndDate OR f.EndDate IS NULL )
        )
FROM    CTE AS t
ORDER BY 1
OPTION  ( MAXRECURSION 0 )

这是 SQL Fiddler 演示。我添加了另一个部门并添加了一个员工。

http://sqlfiddle.com/#!3/5c4ec/1

于 2012-09-17T18:39:07.077 回答