使用审计表时查询帮助

时间:2012-01-05 01:24:53

标签: sql database sql-server-2008 tsql audit-tables

假设我有两个表,一个包含以下列,名为lease_period:

  

tenant_trading_name,suite_id,lease_id,building_id

和另一个名为lease_period_audit,其中包含以下内容:

  

audit_date,audit_type,tenant_trading_name,suite_id,lease_id,building_id

每次在lease_period上更新记录,并在lease_period_audit上输入状态为“Updated”。我正在尝试查找仅对tenant_trading_name字段进行的所有更新,但没有取得任何成功。到目前为止,我有以下内容:

select              lpa.*
from                property.lease_period_audit lpa
inner join          property.lease_period lp on lpa.suite_id = lp.suite_id and lpa.lease_id = lp.lease_id and lpa.building_id = lp.building_id
where               audit_type = 'Updated'
                    and lp.tenant_trading_name <> lpa.tenant_trading_name
order by            1 desc  

我思想过程中的缺陷在哪里?怎么做/我应该怎么想这个?

2 个答案:

答案 0 :(得分:2)

假设审计表还记录了lease_period主键列,为简单起见,此处引用lp_id,您可以尝试以下方法:

  1. 查找audit_type'Updated'的所有行。

  2. audit_date对所有行进行排名,并按lp_id对其进行分区。

  3. audit_date分区lp_id, suite_id, lease_id, building_id对行进行排名。

  4. 获得两个排名之间的差异。

  5. audit_date再次对行进行排名,现在按lp_id, suite_id, lease_id, building_id, (ranking_difference)对其进行分区。

  6. 输出最后一个排名值为2或更高的所有行。

  7. 前四个步骤会产生一个行集,其中对于相同audit_date的每个具有相同suite_id, lease_id, building_idlp_id的连续行(按tenant_trading_name的升序排列)将被唯一区分通过计算为排名#2和&amp;之间的差值的值。 #3。

    在组内,每一行(从第二行开始)将与前一行不同,只有WITH marked AS ( SELECT *, grp = ROW_NUMBER() OVER (PARTITION BY lp_id ORDER BY audit_date) - ROW_NUMBER() OVER (PARTITION BY lp_id, suite_id, lease_id, building_id ORDER BY audit_date) FROM lease_period_audit WHERE audit_type = 'Updated' ), ranked AS ( SELECT *, rnk = ROW_NUMBER() OVER (PARTITION BY lp_id, suite_id, lease_id, building_id, grp ORDER BY audit_date) FROM marked ) SELECT audit_date, lp_id, tenant_trading_name, suite_id, lease_id, building_id FROM ranked WHERE rnk = 2 的值,这正是我们所需要的。因此,我们再次对行进行排名,考虑到我们刚刚获得的“组ID”,然后返回排名为2或更高的每一行。

    这是一个近似的实现:

    {{1}}

    请注意。这假设审计表仅记录实际更改,即不能有两个具有相同主键的连续行,其中所有四列具有相同的值。

答案 1 :(得分:1)

你应该想到这样的事情(伪代码):

编辑:我之前没有意识到lpa表实际上有所有数据,没有必要加入LP

select lpa.*
from   lpa 
join   lpa_before on 
           lpa_before.id = lpa.id and 
           lpa_before.date = 
                  (select max(date) from lpa3 where lpa3.date < lpa.date and lpa.id = lpa3.id)
where  auditytype = 'update' and lpa.name <> lpa_before.name

我希望我能解释一下..(这不是一个简单的解决方案,但那就是我的想法)

英文:

选择LPA寄存器。 加入另一个LPA,它将成为原始LPA之前的LPA。将此LPA_BEFORE称为。 要加入LPA_BEFORE,您必须比较LPA和LPA_BEFORE中的所有ID,LPA_BEFORE日期必须是日期小于原始LPA的LPA的最大值。 将LPA的名称与LPA_BEFORE

进行比较