【问题标题】:Comparing consecutive rows using oracle使用oracle比较连续行
【发布时间】:2015-08-19 10:06:46
【问题描述】:

我有一个看起来像这样的表:

| ID | FROM_DATE | TO_DATE |
------------------------------
| 1  |  1/1/2001 | 2/1/2001|
| 1  |  2/1/2001 | 3/1/2001|
| 1  |  2/1/2001 | 6/1/2001|
| 1  |  3/1/2001 | 4/1/2001|
| 2  |  1/1/2001 | 2/1/2001|
| 2  |  1/1/2001 | 6/1/2001|
| 2  |  2/1/2001 | 3/1/2001|
| 2  |  3/1/2001 | 4/1/2001|

已经按IDFrom_DateTo_date排序。

我想要做的是删除上一行中from_date 早于to_date 并且ID 等于上一行中的ID 的行。所以在这个例子中,我将只删除 3rd6th 行。

我知道我需要某种循环结构来完成此操作,但我不知道如何实现,因为我实际上是一次查看两行。如何在 Oracle 中完成此任务?

编辑:使用 'LAG' 功能更快更容易,我最终也删除了 4th7th 行 - 这不是我想要做的.例如,当它到达 row 4 时,它应该比较 row 2 中的 'from_date' 和 'to_date'(而不是第 3 行,因为第 3 行应该是已删除)。

【问题讨论】:

    标签: sql oracle loops date sql-delete


    【解决方案1】:

    您可以使用lag 窗口函数来识别这些行:

    DELETE FROM mytable
    WHERE rowid IN (SELECT rowid
                    FROM   (SELECT rowid, from_date, 
                                   LAG(to_date) OVER 
                                      (PARTITION BY id
                                       ORDER BY from_date, to_date) 
                                      AS lag_to_date
                            FROM   my_table) t
                    WHERE  from_date < lag_to_date)
    

    【讨论】:

    • 如果您不熟悉 LAG 功能,请参阅 documentation. LAG 允许您一次访问多行而无需使用自联接。
    • 这实际上让我删除了比我预期更多的行 - 它还删除了第 4 行和第 7 行。我应该更清楚,我希望它遍历每一行,将 from_date 与前一个 to_date 进行比较,如果更早,则删除该行。我将编辑我的问题以反映这一点。
    • 暂别我的评论 - 我在引入时错误地将 'rowid' 替换为 'id'。我没有意识到 'rowid' 很特别,谢谢!
    • @mjavon 是的,rowid 是一个伪列,它返回行的地址。一种内置的主键,如果你愿意的话。
    猜你喜欢
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    相关资源
    最近更新 更多