SQL 服务器视图:从审计中分配历史员工部门 table

SQL Server view : assign historic employee department from an audit table

我正在创建一个 SQL 服务器视图。我有来自时间管理系统的员工数据,每天的上班和下班时间安排在 table 中,如下所示,这只是一个示例,有 100 条员工记录。

DATE           USERID    CLOCK
--------------------------------
2020-02-25      1234    08:00:00
2020-02-25      1234    17:00:00

有一个部门和 CostCode table,但它只包含当前部门和 CostCode,没有任何历史信息。有一个审计 table 如下所示,CHANGEDATE 是日期时间格式,还记录了更改的时间。

CHANGEDATE          USERID  CHANGETYPE  NEWVALUE
-------------------------------------------
2019-01-01 hh:mm:ss 1234    DEPARTMENT  Warehouse
2019-01-01 hh:mm:ss 1234    DEPARTMENT  Stores
2019-05-01 hh:mm:ss 1234    COSTCODE    Store1
2020-02-25 hh:mm:ss 1234    DEPARTMENT  Shipping
2020-02-25 hh:mm:ss 1234    COSTCODE    Dock1

我需要做的是将时间的部门和成本代码分配给时钟 in/out 数据,如下所示,这样我就可以看到他们被分配到的部门和成本代码时钟的日期。使用上面的方法,员工 1234 在 01/05/2019 和 25/02/2020 之间的每个时钟都被分配部门 = Stores 和成本代码 = Store1,25/02/2020 之前和之后的每个时钟都是部门 = Shipping 和成本代码= Dock1 等

DATE       USERID     CLOCK    DEPARTMENT   COSTCODE
-----------------------------------------------------
2020-02-24  1234    09:00:00    Stores      Store1
2020-02-24  1234    18:00:00    Stores      Store1
2020-02-25  1234    08:00:00    Shipping    Dock1
2020-02-25  1234    17:00:00    Shipping    Dock1

有人可以帮忙吗?提前致谢。

我会构建一个中间视图或 CTE,其中包含开始和结束日期的每个属性的清晰历史记录,然后使用日期范围条件将其与您的时钟数据连接起来:

WITH changes_periods AS (
  SELECT
    c1.USERID,
    c1.CHANGETYPE AS ATTR_TYPE,
    c1.NEWVALUE AS ATTR_VALUE,
    c1.CHANGEDATE AS VALID_FROM,
    COALESCE(MIN(c2.CHANGEDATE), '20990101') AS VALID_BEFORE
  FROM changes c1
    LEFT JOIN changes c2 ON c1.USERID=c2.USERID AND c1.CHANGETYPE=c2.CHANGETYPE AND c1.CHANGEDATE<c2.CHANGEDATE
  GROUP BY c1.USERID,c1.CHANGETYPE, c1.NEWVALUE, c1.CHANGEDATE
)
SELECT
  c.DATE,
  c.USERID,
  c.CLOCK,
  dep.ATTR_VALUE as DEPARTMENT,
  cc.ATTR_VALUE as COSTCODE
FROM clockdata c
  LEFT JOIN changes_periods dep ON
    c.USERID=dep.USERID
    and dep.ATTR_TYPE='DEPARTMENT'
    and c.DATE>=dep.VALID_FROM and c.DATE<dep.VALID_BEFORE
  LEFT JOIN changes_periods cc ON
    c.USERID=cc.USERID
    and cc.ATTR_TYPE='COSTCODE'
    and c.DATE>=cc.VALID_FROM and c.DATE<cc.VALID_BEFORE