How to display employee status day wise in a month

醉酒当歌 提交于 2019-12-13 09:55:25

问题


Below is my table structure and data.

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

when I pass month start date and end date in my query('01-MAY-2019' AND '31-MAY-2019') the query should display the data like below for EMPLID 722243 and 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

same should display until 19-MAY-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

Please help me out on this.


回答1:


Oracle Setup:

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;

Query: All PER_ORG values:

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

Output:

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    

Query: Just CWR values:

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

Output:

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<>fiddle here



来源:https://stackoverflow.com/questions/57185095/how-to-display-employee-status-day-wise-in-a-month

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!