【问题标题】:Postgres SQL for joining parent-child audit tables用于连接父子审计表的 Postgres SQL
【发布时间】:2011-04-19 22:42:52
【问题描述】:

我们使用"1 audit table for each monitored Table" 设计;然而,在我们的例子中,emp(PARENT) 表有一个子表emp_address,它也需要被监控,所以我们有emp_auditemp_addr_audit tables

postgres 审计 SQL:如何连接 PARENT 和 CHILD 表以进行报告。

/* Employee table */    
create table emp (
 emp_id integer primary key,
 empnum  integer,
 empname varchar(50),
);

/* Address table */    
create table emp_addr (
 addr_id integer primary key,
 emp_id integer, -- references table emp
 line1 varchar(30),
);

/* Audit table for emp table */    
create table emp_audit (
 operation   character(1),
 emp_id integer,
 empnum  integer,
 empname varchar(50),
 updatetime timestamp,
 txid bigint
);

/* Audit table for emp_addr table */    
create table emp_addr_audit (
 operation   character(1),
 addr_id integer,
 emp_id integer,
 line1 varchar(30),
 updatetime timestamp,
 txid bigint
);

我们使用 hibernate(java) 进行持久化,hibernate 只更新那些在更新操作中修改了列的表。鉴于此,对于 emp_audit 表中的 1 行,我可能在 emp_addr_audit 表中有多个(比如 5)行。反之亦然。

每个交易(修改)报告需要 1 行。 该报告将包含以下列

empname、line1、操作(插入/删除/更新)、更新时间

让我们考虑 2 个场景来了解需要什么:

  1. 在初始事务中仅创建emp 属性。然后在单独的事务中,创建emp_addr 中的相应行。所以,现在,emp_audit 表中有 1 行,emp_addr_audit 表中有 1 行。该报告将有 2 行(每笔交易各一行)。
  2. empemp_addr 属性均在单个事务中创建。这将确保emp_audit 中有 1 行,emp_addr_audit 中有 1 行。现在,报告将只有 1 行(因为两个表行都是在单个事务中创建的)。

场景
事务 #1:我在 emp 和 emp_addr 中都插入了一行。这会在 emp_audit 和 emp_addr_audit 中各产生一行。(INSERT)
事务 #2:我更新了上面的 emp' 属性。这会在 emp_audit 中产生一个 UPDATE 行。
事务 #3:我更新了上述 emp_addr 的属性。这会在 emp_addr_audit 中产生一个 UPDATE 行。

我尝试了以下 SQL #1,它返回了 3 行(如预期的那样);

SQL #1

SELECT emp.*, addr.*
 FROM  emp_audit emp 
 FULL OUTER JOIN emp_addr_audit addr USING(emp_id, txid);

但是,当我在 SQL 中添加 where 子句时,它只返回 2 行。丢失的行是事务 #3 的结果,其中只有 emp_addr 表行已更新,而 emp 表行未受影响。
SQL #2

SELECT emp.*, addr.*
 FROM  emp_audit emp 
        FULL OUTER JOIN emp_addr_audit addr USING(emp_id, txid);
WHERE  emp.empnum = 20;

什么 SQL 仍然能够为我的 3 个事务获取 3 行,以便我仍然可以根据 empnum 过滤掉?

【问题讨论】:

  • 那么,你想加入employee auditemployee address 吗?
  • 抱歉给您带来了困惑。我修复了错误。我正在尝试将 emp_audit 与 emp_addr_audit 一起加入。

标签: sql postgresql parent-child audit full-outer-join


【解决方案1】:

FULL JOIN 将从两个表中创建一个表,并用 NULL 值填充空(不匹配)行。当您仅选择 emp.empnum = 20 的行时,它当然不会返回 emp.empnum 中具有 NULL 的最后一行。

也许你只能在 emp_id 上加入,然后做一些 GROUP BY txid。但这不会那么容易。您可能必须始终对两个表进行更新。或者使用一些更高级的逻辑(例如:选择一个 emp_id 的所有事务,其中一侧为空,直到下一个完整行,并用最后一个完整行填充缺失的部分)。

【讨论】:

    猜你喜欢
    • 2023-01-10
    • 2017-03-07
    • 1970-01-01
    • 2022-11-15
    • 2015-08-01
    • 2022-12-14
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多