如何根据要删除的行调整其他行数据

Posted

技术标签:

【中文标题】如何根据要删除的行调整其他行数据【英文标题】:how to adjust other rows data based on a to be deleted row 【发布时间】:2015-05-18 17:06:29 【问题描述】:

我在一个人的 oracle 表中有以下地址数据[未显示到特定人员和其他几个字段的映射]。

**StartDate                 Address             EndDate** <br/>

1。 2015 年 1 月 10 日 10:52:23 1 格里姆肖 2015 年 1 月 12 日 11:30:15 2. 2015 年 1 月 12 日 11:30:15 2 阿什伍德 2015 年 1 月 15 日 03:17:05 3。 15-JAN-2015 03:17:05 5 绿色驱动器 13-FEB-2015 06:03:55 4. 2015 年 2 月 13 日 06:03:55 6 Lightfoot 关闭 2015 年 2 月 18 日 17:37:01 5. 2015 年 2 月 18 日 17:37:01 7 Lightfoot Ln 2015 年 3 月 15 日 01:19:31

所有这些地址都有正确的日期顺序。这意味着,一个特定的人总是在 2015 年 1 月 10 日到 2015 年 3 月 15 日之间拥有一个有效地址]。 要求是,说删除其中一个地址并相应地调整日期,以便不留空隙。我们有一个脚本可以删除特定行但无法相应地更新其他行中的日期。 例如,如果我删除上述集合中的第 3 行,则最终结果应如下所示

**StartDate                 Address             EndDate** <br/>

1。 2015 年 1 月 10 日 10:52:23 1 格里姆肖 2015 年 1 月 12 日 11:30:15 2. 2015 年 1 月 12 日 11:30:15 2 阿什伍德 2015 年 2 月 13 日 06:03:55 3. 2015 年 2 月 13 日 06:03:55 6 Lightfoot 关闭 2015 年 2 月 18 日 17:37:01 4. 2015 年 2 月 18 日 17:37:01 7 Lightfoot Ln 2015 年 3 月 15 日 01:19:31

第 2 行的 EndDate 更新为已删除行的 EndDate [即第 3 行]。

注意: 此处的记录编号 1-5 仅用于说明目的,表格中没有任何此类列。

【问题讨论】:

你使用 sql server 还是 oracle? Oracle...主要是寻找一些创新的 SQL 或 pl/sql 方式,否则... 它是否总是更新以已删除行的开始日期结束的行..在您的示例中,已删除行的开始日期为 15,您更新结束日期为 15 的行..您更新结束日期与删除行的结束日期..总是一样吗? 你试过我的答案了吗? 【参考方案1】:

我通过假设以下条件编写了这个触发器

    在表格中会有一个person_id 列来代表每个人 删除行时,将更新已删除行的End datestart date

    删除行时,删除行的EndDate列值将用于更新上述行的EndDate

    create or replace trigger product_update
    
    BEFORE DELETE on your_table_name
    for each row
    

    开始

    UPDATE your_table_name
       SET EndDate = :new.EndDate,
     WHERE EndDate = :new.StartDate
     AND PERSON_ID = :new.PERSON_ID;  
    

    结束;​

【讨论】:

【参考方案2】:

我为您展示的设计模式创造了“行跨越依赖”一词。那是一列依赖于另一列但在不同行中的地方。问题在于,维护数据完整性是一场噩梦——正如您所见。

我建议完全删除 EndDate 列。如果那是您无权做的事情,那么您可以简单地忽略它。 EndDate 字段没有任何用途,只会让您的生活变得悲惨。

仅使用 StartDate 字段,地址从那个时间开始并持续到下一个更高的 StartDate 值。因此,如果您删除指定的行,则从 1 月 12 日开始的地址现在将持续到 2 月 13 日。您稍后可以插入一个新行,其 StartDate 为 1 月 20 日,它非常适合序列:1 月 12 日-> 1 月 20 日 -> 2 月 13 日...

要意识到的重要一点是每一行都独立于其他行。您可以随心所欲地插入、删除和更新,只要日期值保持唯一,序列就不会中断。唯一性仅由作为 PK 一部分的 StartDate 强制执行。

自动地,无需您付出额外的努力,就可以保持完整的日期序列,没有间隙,也不会重复。这一点怎么强调都不为过:不可能“打破”这个顺序。即使两个日期仅相差几毫秒(这可能意味着其中一个日期值错误),序列仍然保持不变。如果其中一个日期错误,请将其更新为正确的值,而不必担心会破坏序列的完整性。

查询哪个地址在特定日期处于活动状态实际上非常简单:

select  a.StartDate, a.Address
from    Addresses a
where   StartDate =(
        select  Max( StartDate )
        from    Addresses
        where   PersonID = a.PersonID
            and StartDate <= :AsOfDate );

如果必须,您可以复制 StartDate/EndDate 表单:

select  a.StartDate, a.Address, a1.StartDate as EndDate
from    Addresses a
left join Addesses a1
    on  a1.PersonID = a.PersonID
    and a1.StartDate =(
        select  Min( StartDate )
        from    Addresses
        where   PersonID = a.PersonID
            and StartDate > a.StartDate );

最后一个日期 - 代表“当前”地址的日期 - 将显示一个 EndDate 值NULL,这提供了标记当前行的额外好处。

事实上,您可以根据第二个查询创建一个视图,并为您的用户提供他们习惯看到的内容。另一个方便的视图将基于第一个查询,但使用sysdate 而不是参数。那将只显示当前地址。无论哪种方式,现在您都不必为保持一行的 StartDate 值和另一行的 EndDate 值不断同步而烦恼。

【讨论】:

以上是关于如何根据要删除的行调整其他行数据的主要内容,如果未能解决你的问题,请参考以下文章

删除作为其他行子字符串的行

如何删除EXCEL表中的大量数据行,要删除的行数大概8万

怎样根据内容自动调整excel表格的行高列宽?

如何设置自动布局,以便 UILabel 调整大小并根据需要移动其他视图

根据“如果单元格中的字符串”条件删除熊猫列中的行

如何根据在选取器视图中选择的行组件更新表视图数据