【问题标题】:SQL comparing record versions in the same tableSQL比较同一张表中的记录版本
【发布时间】:2012-03-30 12:04:11
【问题描述】:

我有一个每周一加载员工记录的表。装载日期存储在记录中。我需要总结从一周到下一周的总更改(添加/更新)记录。

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

我不确定这是否是一个很好的方法,如果我能得到任何关于我的方法的反馈,或者关于实现我目标的更好方法的建议,我将不胜感激。

谢谢。

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;

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

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

    1. 在查找“为员工加载数据的最后日期”时,请尝试添加一个表格来记录加载过程,其中包含加载时间。这将提高您的性能,并且您不必使用“select MAX(LOAD_DATE) from ...”两次。
    2. 您可以添加一个额外的列来记录记录的更新时间;这样当您在寻找更改的记录时,只是为了比较记录的“更新时间”和“加载时间”。在此表上放置更新触发器将是修改“更新时间”的更好策略。

    根据上面的建议,重点是防止两次加入表格并触摸数据页。由于您的报告是检索数据的“SUM”,因此您不必使用“EMPLOYEES”表的全部信息。

    首先,代码更清楚地符合您“汇总更改的记录总数”的意图。其次,数据库只需要索引来“计数”您的数据度量(当然,“load_date”上的适当索引),因此性能应该优于您的“JOIN-SELF-TABLE”方法。

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

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

    1. 合理预期中的可接受性能。
    2. 在不牺牲性能的情况下,让代码更具可读性。

    如果您有一个性能较差的复杂 SQL,请原谅我重复我的观点。以后为了提高性能而修改 SQL 的风险更大。

    【讨论】:

    • 感谢迈克的建议。将 MAX(Load_Date) 值放入变量中并使用它而不是两次使用 MAX 是否有意义?
    • 那会比你原来的版本好。在最坏的情况下,请确保“load_date”上有一个索引。
    • 除此之外,这是获取我需要的信息的好方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多