找出两行中的差异

时间:2015-05-19 03:50:58

标签: sql-server

我有一个数据库,用于跟踪员工记录的变化。 我还有一份报告显示有变更的员工和在“经理”领域没有价值的员工。

这意味着什么 - 如果Manager为null - 工作人员将出现在报告中 - 并且可能只有1行。

如果工作人员在报告期间发生了变化,他们将在报告中有两行。 报告期和CURRENT州最早的变化。

SQL用于填充网页。 报告看起来像这样; (我故意在示例中保持简单)

ID   StaffName  Manager field3  field4  field5  field6  enddate
104  Mathew     Gavin      A       A       A      A     '2015-03-01'
107  Mathew     Gavin      B       A       A      A     NULL
89   Gavin      Lachlan    A       A       A      A     '2015-03-01'
100  Gavin      Lachlan    A       B       A      A     NULL
123  Gus                   A       A       A      A     NULL
178  Mark                  A       A       A      A     NULL

Gavin发生了变化,因此在报告中出现了两次。 只有第二行(enddate不为null)才可编辑。

Gus和Mark出现在报告中,因为他们没有分配经理 它们都是可编辑的 - 这是正确的。

但是,Mathew不应出现在报告中。 这是我需要帮助的问题。

目前,我的SQL会返回所有员工,无论他们有什么变化。 但我只关心改变是否在以下列之一; 经理或Field4或5。 Field3(或6)的变化并不能保证Mathew被纳入报告中。

这是我正在使用的SQL,仅限于我在示例数据中提供的字段。

SELECT
    distinct *
FROM
    (
    -- get LATEST ROW where NOT CLOSED
    SELECT 
        pg1.id, 
        pg1.lastname, 
        pg1.firstnames, 
        pg3.firstnames + ' ' + pg3.lastname AS Manager,
        pg4.activeStartDate, 
        pg4.activeEndDate
    FROM
        pgEmployees pg1
            LEFT JOIN pgEmployees pg3 ON pg3.id = pg1.managerId
    WHERE 
        pg1.id in 
        (
        Select Distinct ID From pgEmployees
        Where activeEndDate is null
        AND
        (activeStartDate between '#lsdateformat(arguments.startDate, "YYYY-MM-DD")# 00:00:00.000' and '#lsdateformat(arguments.endDate, "YYYY-MM-DD")# 23:59:59.999')
      )

    --GET THE LATEST OLD ROW
    UNION 
        SELECT
            pg4.id, 
            pg4.lastname, 
            pg4.firstnames, 
            pg5.firstnames + ' ' + pg5.lastname AS Manager,
            pg4.activeStartDate, 
            pg4.activeEndDate
        FROM
            pgEmployees pg4
            LEFT JOIN pgEmployees pg5
                ON pg5.id = pg4.managerId
            INNER JOIN(
                SELECT 
                    adUserId,
                    max(id) id
                FROM 
                    pgemployees
                WHERE
                    activeEndDate IS NOT NULL   
                AND
                    activeEndDate < '#lsdateformat(arguments.endDate, "YYYY-MM-DD")# 23:59:59.999'
                GROUP BY
                    adUserId
            ) SubQ ON (
                pg4.adUserId = SubQ.adUserId and pg4.id = SubQ.id
            )
        WHERE
            (pg4.activeStartDate < '#lsdateformat(arguments.endDate, "YYYY-MM-DD")# 23:59:59.999' or pg4.activeStartDate is null)
        AND
            (pg4.activeEndDate IS NOT NULL) 
        AND
            (pg4.activeEndDate < '#lsdateformat(arguments.endDate, "YYYY-MM-DD")# 23:59:59.999')

    -- GET THE STAFF THAT HAVE NO MANAGER
    UNION 
        SELECT 
            pg6.id, 
            pg6.lastname, 
            pg6.firstnames, 
            NULL AS Manager,
            pg6.activeStartDate, 
            pg6.activeEndDate
        FROM
            pgEmployees pg6
        WHERE
            (pg6.managerAD IS NULL)
        AND
            (pg6.activeEndDate IS NULL)
    )Subq
ORDER BY
    lastname ASC, 
    firstnames ASC,
    id; 

0 个答案:

没有答案