如何在一个月中每天显示员工状态

时间:2019-07-24 14:17:51

标签: sql oracle11g

下面是我的表结构和数据。

EMPLID  EMPL_RCD    EFFDT   Eff_SEQ HR_STATUS   PER_ORG
722243  0         21-Nov-18 0   A            CWR
722243  0         15-May-19 0   A            CWR
722243  0         20-May-19 0   I            CWR
722243  1         20-May-19 0   A            EMP
120707  1         14-May-19 0   A            EMP
120707  0         29-May-19 0   I            EMP
120707  1         29-May-19 0   I            EMP
120707  2         29-May-19 0   A            CWR

当我在查询中传递月份开始日期和结束日期(“ 01-MAY-2019”和“ 31-MAY-2019”)时,该查询应显示类似EMPLID 722243和120707的数据。

EMPLID               Date               PER_ORG  HR_STATUS
---------------------------------------------------------
722243                01-MAY-19      CWR          A
722243                02-MAY-19      CWR          A
722243                03-MAY-19      CWR          A
722243                04-MAY-19      CWR          A

应显示相同,直到19年5月19日

722243                19-MAY-19      CWR           A
120707                29-MAY-19      CWR           A
120707                30-MAY-19      CWR           A
120707                31-MAY-19      CWR           A

请帮助我。

1 个答案:

答案 0 :(得分:0)

Oracle设置

CREATE TABLE table_name ( EMPLID, EMPL_RCD, EFFDT, Eff_SEQ, HR_STATUS, PER_ORG ) AS
SELECT 722243, 0, DATE '2018-11-21', 0, 'A', 'CWR' FROM DUAL UNION ALL
SELECT 722243, 0, DATE '2019-05-15', 0, 'A', 'CWR' FROM DUAL UNION ALL
SELECT 722243, 0, DATE '2019-05-20', 0, 'I', 'CWR' FROM DUAL UNION ALL
SELECT 722243, 1, DATE '2019-05-20', 0, 'A', 'EMP' FROM DUAL UNION ALL
SELECT 120707, 1, DATE '2019-05-14', 0, 'A', 'EMP' FROM DUAL UNION ALL
SELECT 120707, 0, DATE '2019-05-29', 0, 'I', 'EMP' FROM DUAL UNION ALL
SELECT 120707, 1, DATE '2019-05-29', 0, 'I', 'EMP' FROM DUAL UNION ALL
SELECT 120707, 2, DATE '2019-05-29', 0, 'A', 'CWR' FROM DUAL;

查询:所有PER_ORG值:

WITH bounds ( start_date, end_date ) AS (
  SELECT DATE '2019-05-01', DATE '2019-05-31' FROM DUAL
),
calendar ( dt ) AS (
  SELECT start_date + LEVEL - 1
  FROM   bounds
  CONNECT BY start_date + LEVEL - 1 <= end_date
),
table_name_with_prev_status ( emplid, effdt, hr_status, per_org, prev_hr_status ) AS (
  SELECT EMPLID,
         EFFDT,
         HR_STATUS,
         PER_ORG,
         LAG( HR_STATUS, 1, 'I' )
           OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY EFFDT, EMPL_RCD )
  FROM   table_name
),
statuses ( emplid, effdt, hr_status, per_org ) AS (
  SELECT EMPLID,
         DT,
         COALESCE(
           HR_STATUS,
           LAG( HR_STATUS ) IGNORE NULLS
             OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY DT ),
           LEAD( PREV_HR_STATUS ) IGNORE NULLS
             OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY DT )
         ),
         PER_ORG
  FROM   calendar c
         LEFT OUTER JOIN table_name_with_prev_status t
         PARTITION BY ( t.EMPLID, t.PER_ORG )
         ON ( c.dt = t.effdt )
)
SELECT *
FROM   statuses
WHERE  HR_STATUS = 'A'
ORDER BY emplid, effdt

输出

EMPLID | EFFDT     | HR_STATUS | PER_ORG
-----: | :-------- | :-------- | :------
120707 | 14-MAY-19 | A         | EMP    
120707 | 15-MAY-19 | A         | EMP    
120707 | 16-MAY-19 | A         | EMP    
120707 | 17-MAY-19 | A         | EMP    
120707 | 18-MAY-19 | A         | EMP    
120707 | 19-MAY-19 | A         | EMP    
120707 | 20-MAY-19 | A         | EMP    
120707 | 21-MAY-19 | A         | EMP    
120707 | 22-MAY-19 | A         | EMP    
120707 | 23-MAY-19 | A         | EMP    
120707 | 24-MAY-19 | A         | EMP    
120707 | 25-MAY-19 | A         | EMP    
120707 | 26-MAY-19 | A         | EMP    
120707 | 27-MAY-19 | A         | EMP    
120707 | 28-MAY-19 | A         | EMP    
120707 | 29-MAY-19 | A         | CWR    
120707 | 30-MAY-19 | A         | CWR    
120707 | 31-MAY-19 | A         | CWR    
722243 | 01-MAY-19 | A         | CWR    
722243 | 02-MAY-19 | A         | CWR    
722243 | 03-MAY-19 | A         | CWR    
722243 | 04-MAY-19 | A         | CWR    
722243 | 05-MAY-19 | A         | CWR    
722243 | 06-MAY-19 | A         | CWR    
722243 | 07-MAY-19 | A         | CWR    
722243 | 08-MAY-19 | A         | CWR    
722243 | 09-MAY-19 | A         | CWR    
722243 | 10-MAY-19 | A         | CWR    
722243 | 11-MAY-19 | A         | CWR    
722243 | 12-MAY-19 | A         | CWR    
722243 | 13-MAY-19 | A         | CWR    
722243 | 14-MAY-19 | A         | CWR    
722243 | 15-MAY-19 | A         | CWR    
722243 | 16-MAY-19 | A         | CWR    
722243 | 17-MAY-19 | A         | CWR    
722243 | 18-MAY-19 | A         | CWR    
722243 | 19-MAY-19 | A         | CWR    
722243 | 20-MAY-19 | A         | EMP    
722243 | 21-MAY-19 | A         | EMP    
722243 | 22-MAY-19 | A         | EMP    
722243 | 23-MAY-19 | A         | EMP    
722243 | 24-MAY-19 | A         | EMP    
722243 | 25-MAY-19 | A         | EMP    
722243 | 26-MAY-19 | A         | EMP    
722243 | 27-MAY-19 | A         | EMP    
722243 | 28-MAY-19 | A         | EMP    
722243 | 29-MAY-19 | A         | EMP    
722243 | 30-MAY-19 | A         | EMP    
722243 | 31-MAY-19 | A         | EMP    

查询:仅CWR个值:

WITH bounds ( start_date, end_date ) AS (
  SELECT DATE '2019-05-01', DATE '2019-05-31' FROM DUAL
),
calendar ( dt ) AS (
  SELECT start_date + LEVEL - 1
  FROM   bounds
  CONNECT BY start_date + LEVEL - 1 <= end_date
),
table_name_with_prev_status ( emplid, effdt, hr_status, per_org, prev_hr_status ) AS (
  SELECT EMPLID,
         EFFDT,
         HR_STATUS,
         PER_ORG,
         LAG( HR_STATUS, 1, 'I' )
           OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY EFFDT, EMPL_RCD )
  FROM   table_name
),
statuses ( emplid, effdt, hr_status, per_org ) AS (
  SELECT EMPLID,
         DT,
         COALESCE(
           HR_STATUS,
           LAG( HR_STATUS ) IGNORE NULLS
             OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY DT ),
           LEAD( PREV_HR_STATUS ) IGNORE NULLS
             OVER ( PARTITION BY EMPLID, PER_ORG ORDER BY DT )
         ),
         PER_ORG
  FROM   calendar c
         LEFT OUTER JOIN table_name_with_prev_status t
         PARTITION BY ( t.EMPLID, t.PER_ORG )
         ON ( c.dt = t.effdt )
)
SELECT *
FROM   statuses
WHERE  HR_STATUS = 'A'
AND    PER_ORG   = 'CWR'
ORDER BY emplid, effdt

输出

EMPLID | EFFDT     | HR_STATUS | PER_ORG
-----: | :-------- | :-------- | :------
120707 | 29-MAY-19 | A         | CWR    
120707 | 30-MAY-19 | A         | CWR    
120707 | 31-MAY-19 | A         | CWR    
722243 | 01-MAY-19 | A         | CWR    
722243 | 02-MAY-19 | A         | CWR    
722243 | 03-MAY-19 | A         | CWR    
722243 | 04-MAY-19 | A         | CWR    
722243 | 05-MAY-19 | A         | CWR    
722243 | 06-MAY-19 | A         | CWR    
722243 | 07-MAY-19 | A         | CWR    
722243 | 08-MAY-19 | A         | CWR    
722243 | 09-MAY-19 | A         | CWR    
722243 | 10-MAY-19 | A         | CWR    
722243 | 11-MAY-19 | A         | CWR    
722243 | 12-MAY-19 | A         | CWR    
722243 | 13-MAY-19 | A         | CWR    
722243 | 14-MAY-19 | A         | CWR    
722243 | 15-MAY-19 | A         | CWR    
722243 | 16-MAY-19 | A         | CWR    
722243 | 17-MAY-19 | A         | CWR    
722243 | 18-MAY-19 | A         | CWR    
722243 | 19-MAY-19 | A         | CWR    

db <>提琴here