从审计表中选择已更改的行

时间:2014-10-23 14:24:18

标签: sql sql-server

我有一个审核表,可以在用户更改零件清单的标称代码时记录。

如您所见,第一列是零件,第二列是更改日期,第三列是标称代码。
这只是数据的一个示例,该表实际上有大量的行。

我想只带回名义代码已更改的那些部分,显示它原来是什么以及它现在是什么。
基本上有一个错误,一个进程不断更改代码,所以我需要知道它之前是什么。

| PART       | DATE CHANG | Nominal code
|------------|------------|-------
| ENGINEWORK | 05/08/2014 | 4000 |
| ENGINEWORK | 06/08/2014 | 4007 |
| ENGINEWORK | 04/09/2014 | 4007 |
| ENGINEWORK | 05/09/2014 | 4007 |
| ENGINEWORK | 15/09/2014 | 4007 |
| ENGINEWORK | 25/09/2014 | 4007 |
| HYPOIDOIL  | 05/08/2014 | 4005 |
| HYPOIDOIL  | 07/08/2014 | 4005 |
| HYPOIDOIL  | 08/08/2014 | 4000 |
| HYPOIDOIL  | 14/08/2014 | 4000 |
| LLB382     | 05/08/2014 | 5000 |
| LLB382     | 07/08/2014 | 4000 |
| LLB382     | 07/08/2014 | 5000 |
| LLB382     | 08/08/2014 | 4000 |
| LLB382     | 14/08/2014 | 4000 |
| LLB382     | 20/10/2014 | 4000 |

2 个答案:

答案 0 :(得分:2)

您似乎想要代码的第一个和最后一个值。我建议使用窗口函数:

with t as (
      select t.*, row_number() over (partition by part order by datechange) as seqnum,
             count(*) over (partition by part) as cnt
      from audit t
     )
select part,
       max(case when seqnum = 1 then nominalcode end) as firstcode,
       max(case when seqnum = cnt then nominalcode end) as lastcode
from t
group by part
having max(case when seqnum = 1 then nominalcode end) <> max(case when seqnum = cnt then nominalcode end);

答案 1 :(得分:0)

我相信每次产品编号更改时,您都会显示所需的结果集。每次代码更改部件的值和事件发生的日期时,此查询都会找到。

    with rankedResult
    as (
        select t.*,
            row_number() over (
                partition by part order by dateChanged
                ) as seqnum
        from Audit t
        )
    select t.part,
        t.code CurrentCode,
        t2.code ChangedToCode,
        t2.dateChanged ChangedDate
    from rankedResult t
    inner join rankedResult t2 on t.part = t2.part
        and t.seqnum = t2.seqnum + 1
        and t.code != t2.code;