事务表上的DB2 SQL时间点数据

时间:2017-11-15 23:16:49

标签: sql db2

我正在尝试从历史记录表中提取时间点信息。该表包含fld_nbr,它映射到诸如工作代码,员工状态,工作地点等属性。如何查找员工在特定日期的状态。数据可能会显示

Employee# fld_nbr beg_date value 
1234      19      10/1/16  AA
1234      14      10/1/16  40
1234      14      1/6/17   46
1234      19      9/15/17  LA

我需要找到状态(fld_nbr 19)和位置(fld_nbr 14)在1/1/17上的状态。我希望我的结果集是fld_nbr 19 = AA和fld_nbr 14 = 40。

编辑以下是我的最终结果:

WITH MO1 AS
(SELECT AFF.AFFILIATE, COUNT(HIS.EMPLOYEE) AS MO1_HC
 FROM
(SELECT HIST.COMPANY, HIST.EMPLOYEE, EMP.ANNIVERS_DATE, EMP.TERM_DATE, 
MAX(CASE WHEN HIST.FLD_NBR = 14 THEN A_VALUE END) AS PROCESS_LEVEL,
MAX(CASE WHEN HIST.FLD_NBR = 14 THEN BEG_DATE END) AS PL_DATE,
MAX(CASE WHEN HIST.FLD_NBR = 15 THEN A_VALUE END) AS DEPARTMENT,
MAX(CASE WHEN HIST.FLD_NBR = 15 THEN BEG_DATE END) AS DEPT_DATE,
MAX(CASE WHEN HIST.FLD_NBR = 20 THEN A_VALUE END) AS EMP_STATUS,
MAX(CASE WHEN HIST.FLD_NBR = 20 THEN BEG_DATE END) AS STATUS_DATE,
DAYS(DATE('2017-10-31')) - DAYS(EMP.ANNIVERS_DATE) AS DOS
FROM DATAMGMT.VW_GCHRHRHISTORY HIST
INNER JOIN (SELECT EMPLOYEE, FLD_NBR, MAX(BEG_DATE) AS MostRecent 
                     FROM DATAMGMT.VW_GCHRHRHISTORY 
                     WHERE BEG_DATE < DATE('2017-10-31') 
                     AND COMPANY = 207
                     AND FLD_NBR IN (14, 15, 20)
                     GROUP BY EMPLOYEE, FLD_NBR) AS tA ON HIST.EMPLOYEE = tA.EMPLOYEE
                                                           AND HIST.FLD_NBR = tA.FLD_NBR
                                                           AND HIST.BEG_DATE = tA.MostRecent
INNER JOIN DATAMGMT.VW_GCHREMPLOYEE EMP ON HIST.EMPLOYEE = EMP.EMPLOYEE
WHERE EMP.ANNIVERS_DATE BETWEEN DATE('2017-10-31') - 365 DAYS AND DATE('2017-10-31') 
AND SUBSTR(HIST.A_VALUE, 1, 1) NOT IN ('T', 'Z')
GROUP BY HIST.COMPANY, HIST.EMPLOYEE, EMP.ANNIVERS_DATE, EMP.TERM_DATE) AS HIS
INNER JOIN DATAMGMT.VW_GCHRAFFILIATE AFF ON AFF.COMPANY = HIS.COMPANY AND AFF.PROCESS_LEVEL = HIS.PROCESS_LEVEL AND AFF.DEPARTMENT = HIS.DEPARTMENT
WHERE HIS.EMP_STATUS IS NOT NULL
GROUP BY AFF.AFFILIATE),
MO2 AS
(SELECT AFF.AFFILIATE, COUNT(HIS.EMPLOYEE) AS MO2_HC
 FROM
(SELECT HIST.COMPANY, HIST.EMPLOYEE, EMP.ANNIVERS_DATE, EMP.TERM_DATE, 
MAX(CASE WHEN HIST.FLD_NBR = 14 THEN A_VALUE END) AS PROCESS_LEVEL,
MAX(CASE WHEN HIST.FLD_NBR = 14 THEN BEG_DATE END) AS PL_DATE,
MAX(CASE WHEN HIST.FLD_NBR = 15 THEN A_VALUE END) AS DEPARTMENT,
MAX(CASE WHEN HIST.FLD_NBR = 15 THEN BEG_DATE END) AS DEPT_DATE,
MAX(CASE WHEN HIST.FLD_NBR = 20 THEN A_VALUE END) AS EMP_STATUS,
MAX(CASE WHEN HIST.FLD_NBR = 20 THEN BEG_DATE END) AS STATUS_DATE,
DAYS(DATE('2017-10-31') - 1 MONTH) - DAYS(EMP.ANNIVERS_DATE) AS DOS
FROM DATAMGMT.VW_GCHRHRHISTORY HIST
INNER JOIN (SELECT EMPLOYEE, FLD_NBR, MAX(BEG_DATE) AS MostRecent 
                     FROM DATAMGMT.VW_GCHRHRHISTORY 
                     WHERE BEG_DATE < DATE('2017-10-31') - 1 MONTH
                     AND COMPANY = 207
                     AND FLD_NBR IN (14, 15, 20)
                     GROUP BY EMPLOYEE, FLD_NBR) AS tA ON HIST.EMPLOYEE = tA.EMPLOYEE
                                                           AND HIST.FLD_NBR = tA.FLD_NBR
                                                           AND HIST.BEG_DATE = tA.MostRecent
INNER JOIN DATAMGMT.VW_GCHREMPLOYEE EMP ON HIST.EMPLOYEE = EMP.EMPLOYEE
WHERE EMP.ANNIVERS_DATE BETWEEN DATE('2017-10-31') - 1 MONTH - 365 DAYS AND DATE('2017-10-31') - 1 MONTH
AND SUBSTR(HIST.A_VALUE, 1, 1) NOT IN ('T', 'Z')
GROUP BY HIST.COMPANY, HIST.EMPLOYEE, EMP.ANNIVERS_DATE, EMP.TERM_DATE) AS HIS
INNER JOIN DATAMGMT.VW_GCHRAFFILIATE AFF ON AFF.COMPANY = HIS.COMPANY AND AFF.PROCESS_LEVEL = HIS.PROCESS_LEVEL AND AFF.DEPARTMENT = HIS.DEPARTMENT
WHERE HIS.EMP_STATUS IS NOT NULL
GROUP BY AFF.AFFILIATE)
SELECT MO1.AFFILIATE, MO1.MO1_HC, MO2.MO2_HC
FROM MO1
INNER JOIN MO2 ON MO2.AFFILIATE = MO1.AFFILIATE

2 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情,它将为您提供每个employee / fld_nbr组合的时间点记录(我忘记了DB2日期文字的语法,您可能需要使用它):

SELECT *
FROM tbl INNER JOIN (SELECT Employee#, fld_nbr, MAX(beg_date) AS MostRecent
                     FROM tbl
                     WHERE beg_date < #1/1/17#
                     GROUP BY Employee#, fld_nbr) AS tA ON tbl.Employee# = tA.Employee#
                                                           AND tbl.fld_nbr = tA.fld_nbr
                                                           AND tbl.beg_date = tA.MostRecent

答案 1 :(得分:0)

我建议使用LEAD()按摩数据以反映日期范围,然后分离在任何单个日期应用的值变得简单。

select
*
from (
    select
        employee
      , fld_nbr
      , beg_date
      , coalesce(lead(beg_date,1) over(partition by Employee, fld_nbr order by beg_date), current date) end_date
    from table1
    ) d
where beg_date <= date('2017-01-01')
and end_date > date('2017-01-01')

e.g。

| employee | fld_nbr |             beg_date |             end_date |
|----------|---------|----------------------|----------------------|
|     1234 |      14 | 2016-10-01T00:00:00Z | 2017-01-06T00:00:00Z |
|     1234 |      19 | 2016-10-01T00:00:00Z | 2017-09-15T00:00:00Z |

nb:我的示例是使用TSQL编写的,因此我的DB2语法可能稍微偏离

Demo