SQL比较同一表中的记录版本

时间:2012-03-14 02:14:19

标签: sql sql-server

我有一张表,可以在星期一每周加载员工记录。加载日期存储在记录中。我需要将总更改(添加/更新)记录从一周汇总到下一周。

这是我到目前为止所拥有的。它将最新加载日期与上一个加载日期相比拆分新记录和更新记录计数。

我不确定这是否是一个很好的方法,我真的很感激我可以得到的关于我的方法的任何反馈,或者建议我更好地实现我的目标。

感谢。

SELECT    
    RIGHT(CONVERT(VARCHAR(10), REPORT_DATE, 103), 7) AS REPORT_DATE,
    [NEW],
    [UPDATED]
FROM
(
SELECT
      CUR.LOAD_DATE AS REPORT_DATE,
      CASE
          WHEN PRV.LOAD_DATE IS NULL THEN 'NEW'
          ELSE 'UPDATED'
      END AS RECORD_TYPE,
      COUNT(*) AS RECORD_COUNT 
FROM
      (SELECT *
       FROM   EMPLOYEES
       WHERE  LOAD_DATE = (SELECT MAX(LOAD_DATE) FROM EMPLOYEES)) CUR
    LEFT OUTER JOIN
            (SELECT *
             FROM   EMPLOYEES
             WHERE LOAD_DATE = (SELECT DATEADD(WEEK,-1,MAX(LOAD_DATE)) FROM EMPLOYEES))PRV
             ON
             CUR.EMPLOYEE_ID = PRV.EMPLOYEE_ID
WHERE
      PRV.EMPLOYEE_ID IS NULL
      OR (CUR.FIRST_NAME != PRV.FIRST_NAME
      OR CUR.LAST_NAME != PRV.LAST_NAME
      OR CUR.ADDRESS1 != PRV.ADDRESS1
      OR CUR.ADDRESS2 != PRV.ADDRESS2
      OR CUR.CITY != PRV.CITY
      OR CUR.STATE != PRV.STATE
      OR CUR.ZIP != PRV.ZIP
      OR CUR.POSITION != PRV.POSITION
      OR CUR.LOCATION != PRV.LOCATION)
GROUP BY
      CUR.LOAD_DATE,
      PRV.LOAD_DATE
) DT
PIVOT
(SUM(RECORD_COUNT) FOR RECORD_TYPE IN ([NEW], [UPDATED])) PV;

1 个答案:

答案 0 :(得分:1)

我有一些建议可以简化您的代码,甚至可以提高查询的性能。

  1. 在查找“为员工加载数据的上次日期”时,请尝试添加一个表来记录加载过程,其中包含加载时间。这样可以提高您的性能,而且您不必两次使用“从...中选择MAX(LOAD_DATE)”。
  2. 您可以添加一个额外的列来记录记录的更新时间;因此,当您正在寻找更改记录时,只需比较记录的“更新时间”和“加载时间”。在此表上添加更新触发器将是修改“更新时间”的更好策略。
  3. 基于以上建议,重点是防止两次加入表并触摸数据页。由于您的报告要检索数据的“SUM”,因此您不必使用“EMPLOYEES”表的全部信息。

    首先,代码更清晰,以符合您对“总更改记录总和”的意图。其次,数据库只需要索引“COUNT”你的数据度量(当然,“load_date”的正确索引),所以性能应该优于你的“JOIN-SELF-TABLE”方法。

    SQL有多种方法可以生成报告。因为SQL是一种难以阅读的语言,所以简洁的写作是一个维护问题。因为在SQL中找出性能问题是一项艰难的工作,所以编写更高效的SQL比以后重写它更有价值。

    根据我的经验,“体面的SQL”是关于:

    1. 合理预期的可接受表现。
    2. 在不牺牲性能的情况下,使代码更具可读性。
    3. 如果你有一个性能很差的复杂SQL,请原谅我重复我的观点。为了提高性能,您有更大的风险来修改SQL。