SQL查询丢失的记录

时间:2019-12-19 07:53:12

标签: sql sql-server

我有一个表,其中包含员工ID,状态,操作和操作日期。我需要为员工创建一个月标记,以查看该员工在一年中的任何月份是否处于活动状态。几个月以来,数据丢失了,因为我只有可用的操作日期。

示例

Employee Id - AAC1000632860QSG,于2008年4月1日被聘用,并于2012年8月1日离职,因此我需要创建一个标志或字段,以帮助我识别该员工在4月,5月,6月等时处于活动状态,直到十一月,这将是两次行动之间的所有月份。

我需要为2个动作之间的缺失行填充所有列,并使用前一个非空白行的值。

希望我能解释我的问题,并希望我能找到解决方案。

MASKID                Status  Reason        Action        Start_Date    MonthDiff
AAC1000632860QSG    Active    Hire001        Hire        2008-04-01    23
AAC1000632860QSG    Active    DATACHG01    Data Change    2010-03-31    1
AAC1000632860QSG    Active    DATACHG01    Data Change    2010-04-01    0
AAC1000632860QSG    Active    DATACHG01    Data Change    2010-04-29    2
AAC1000632860QSG    Active    TRANSFER01    Transfer    2010-06-01    2
AAC1000632860QSG    Active    DATACHG01    Data Change    2010-08-01    1
AAC1000632860QSG    Active    DATACHG01    Data Change    2010-09-01    4
AAC1000632860QSG    Active    DATACHG01    Data Change    2011-01-01    3
AAC1000632860QSG    Active    DATACHG01    Data Change    2011-04-01    4
AAC1000632860QSG    Active    DATACHG01    Data Change    2011-08-01    12
AAC1000632860QSG    Separated YC           Separation    2012-08-01

预期输出:

MASKID           Status Reason     Action      Start_Date MonthDiff 
===================================================================
AAC1000632860QSG Active TRANSFER01 Transfer    2010-06-01 2 
AAC1000632860QSG Active DATACHG01  Data Change 2010-08-01 1 

1 个答案:

答案 0 :(得分:0)

您可以使用递归CTE按月展开它们。

例如。

样本数据:

CREATE TABLE YourEmployeeDataTable
(
  MASKID VARCHAR(16) NOT NULL, 
  Status VARCHAR(10) NOT NULL, 
  Reason VARCHAR(30) NOT NULL, 
  Action VARCHAR(30) NOT NULL, 
  Start_Date DATE NOT NULL, 
  MonthDiff INT
);

INSERT INTO YourEmployeeDataTable
(MASKID, Status, Reason, Action, Start_Date, MonthDiff) VALUES
  ('AAC1000632860QSG', 'Active', 'Hire001',   'Hire',        '2008-04-01', 23)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2010-03-31', 1)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2010-04-01', 0)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2010-04-29', 2)
, ('AAC1000632860QSG', 'Active', 'TRANSFER01', 'Transfer',   '2010-06-01', 2)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2010-08-01', 1)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2010-09-01', 4)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2011-01-01', 3)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2011-04-01', 4)
, ('AAC1000632860QSG', 'Active', 'DATACHG01', 'Data Change', '2011-08-01', 12)
, ('AAC1000632860QSG', 'Separated', 'YC',     'Separation',  '2012-08-01', null)

查询:

WITH RCTE_EMP_DATES AS
(
  SELECT MASKID, Status, Reason, Action
  , Start_Date AS startDate
  , LEAD(Start_Date,1,Start_Date) OVER (PARTITION BY MASKID ORDER BY Start_Date) AS endDate
  , IIF(MonthDiff>0,1,0) AS MonthDiff
  , 0 AS lvl
  FROM YourEmployeeDataTable

  UNION ALL

  SELECT MASKID, Status, null, null
  , DATEADD(DAY,1,EOMONTH(DATEADD(month,1,startDate),-1))
  , endDate
  , 1
  , lvl + 1
  FROM RCTE_EMP_DATES
  WHERE startDate < DATEADD(month,-1,endDate)
)
SELECT * 
FROM RCTE_EMP_DATES
ORDER BY MASKID, startDate

结果:

MASKID           | Status    | Reason     | Action      | startDate           | endDate             | MonthDiff | lvl
:--------------- | :-------- | :--------- | :---------- | :------------------ | :------------------ | --------: | --:
AAC1000632860QSG | Active    | Hire001    | Hire        | 01/04/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/05/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | null       | null        | 01/06/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   2
AAC1000632860QSG | Active    | null       | null        | 01/07/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   3
AAC1000632860QSG | Active    | null       | null        | 01/08/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   4
AAC1000632860QSG | Active    | null       | null        | 01/09/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   5
AAC1000632860QSG | Active    | null       | null        | 01/10/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   6
AAC1000632860QSG | Active    | null       | null        | 01/11/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   7
AAC1000632860QSG | Active    | null       | null        | 01/12/2008 00:00:00 | 31/03/2010 00:00:00 |         1 |   8
AAC1000632860QSG | Active    | null       | null        | 01/01/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |   9
AAC1000632860QSG | Active    | null       | null        | 01/02/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  10
AAC1000632860QSG | Active    | null       | null        | 01/03/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  11
AAC1000632860QSG | Active    | null       | null        | 01/04/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  12
AAC1000632860QSG | Active    | null       | null        | 01/05/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  13
AAC1000632860QSG | Active    | null       | null        | 01/06/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  14
AAC1000632860QSG | Active    | null       | null        | 01/07/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  15
AAC1000632860QSG | Active    | null       | null        | 01/08/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  16
AAC1000632860QSG | Active    | null       | null        | 01/09/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  17
AAC1000632860QSG | Active    | null       | null        | 01/10/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  18
AAC1000632860QSG | Active    | null       | null        | 01/11/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  19
AAC1000632860QSG | Active    | null       | null        | 01/12/2009 00:00:00 | 31/03/2010 00:00:00 |         1 |  20
AAC1000632860QSG | Active    | null       | null        | 01/01/2010 00:00:00 | 31/03/2010 00:00:00 |         1 |  21
AAC1000632860QSG | Active    | null       | null        | 01/02/2010 00:00:00 | 31/03/2010 00:00:00 |         1 |  22
AAC1000632860QSG | Active    | null       | null        | 01/03/2010 00:00:00 | 31/03/2010 00:00:00 |         1 |  23
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 31/03/2010 00:00:00 | 01/04/2010 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/04/2010 00:00:00 | 29/04/2010 00:00:00 |         0 |   0
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 29/04/2010 00:00:00 | 01/06/2010 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/05/2010 00:00:00 | 01/06/2010 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | TRANSFER01 | Transfer    | 01/06/2010 00:00:00 | 01/08/2010 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/07/2010 00:00:00 | 01/08/2010 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/08/2010 00:00:00 | 01/09/2010 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/09/2010 00:00:00 | 01/01/2011 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/10/2010 00:00:00 | 01/01/2011 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | null       | null        | 01/11/2010 00:00:00 | 01/01/2011 00:00:00 |         1 |   2
AAC1000632860QSG | Active    | null       | null        | 01/12/2010 00:00:00 | 01/01/2011 00:00:00 |         1 |   3
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/01/2011 00:00:00 | 01/04/2011 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/02/2011 00:00:00 | 01/04/2011 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | null       | null        | 01/03/2011 00:00:00 | 01/04/2011 00:00:00 |         1 |   2
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/04/2011 00:00:00 | 01/08/2011 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/05/2011 00:00:00 | 01/08/2011 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | null       | null        | 01/06/2011 00:00:00 | 01/08/2011 00:00:00 |         1 |   2
AAC1000632860QSG | Active    | null       | null        | 01/07/2011 00:00:00 | 01/08/2011 00:00:00 |         1 |   3
AAC1000632860QSG | Active    | DATACHG01  | Data Change | 01/08/2011 00:00:00 | 01/08/2012 00:00:00 |         1 |   0
AAC1000632860QSG | Active    | null       | null        | 01/09/2011 00:00:00 | 01/08/2012 00:00:00 |         1 |   1
AAC1000632860QSG | Active    | null       | null        | 01/10/2011 00:00:00 | 01/08/2012 00:00:00 |         1 |   2
AAC1000632860QSG | Active    | null       | null        | 01/11/2011 00:00:00 | 01/08/2012 00:00:00 |         1 |   3
AAC1000632860QSG | Active    | null       | null        | 01/12/2011 00:00:00 | 01/08/2012 00:00:00 |         1 |   4
AAC1000632860QSG | Active    | null       | null        | 01/01/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |   5
AAC1000632860QSG | Active    | null       | null        | 01/02/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |   6
AAC1000632860QSG | Active    | null       | null        | 01/03/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |   7
AAC1000632860QSG | Active    | null       | null        | 01/04/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |   8
AAC1000632860QSG | Active    | null       | null        | 01/05/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |   9
AAC1000632860QSG | Active    | null       | null        | 01/06/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |  10
AAC1000632860QSG | Active    | null       | null        | 01/07/2012 00:00:00 | 01/08/2012 00:00:00 |         1 |  11
AAC1000632860QSG | Separated | YC         | Separation  | 01/08/2012 00:00:00 | 01/08/2012 00:00:00 |         0 |   0

db <>小提琴here

上进行测试