【问题标题】:Delete all but some rows - Oracle删除除某些行之外的所有行 - Oracle
【发布时间】:2009-11-27 13:06:27
【问题描述】:

我想从表中删除一组行。我可以决定需要删除哪些行。仅当行数超过 5(基于条件)时,我才会从表中删除行。

考虑这个样本数据

ID--Col1--Col2--
1   A      X
2   A      X
3   A      X
4   A      X
5   A      X
6   A      X
7   A      X
8   A      X
9   A      X
10   A      X
11   B      X
12   B      X
13   B      X
14   B      X
15   C      X
16   C      X
17   C      X
18   D      X
19   D      X

我想删除 {*, A, X} 的 5 行,我需要保留其中的 5 行(无论哪一行)。我不会删除 B、C 和 D,因为它们的数量少于 5 个。

喜欢

delete from tableA
 --- I can decide on the rows to delete based on two conditions.
 where col1 = someCondition
   and col2 = someOtherCondition
   and rownum > 5 --- This dint work. I checked.

我想也许我需要以编程方式。非常感谢任何建议。

【问题讨论】:

  • 没用是什么意思 - 你的问题不够清楚,我无法理解

标签: sql oracle


【解决方案1】:

这将删除 col1 和 col2 的每个唯一组合的所有行,而不是按 rowid 排序的前五行

delete from my_table
where rowid in
  (
  select rowid
  from
    (
    select rowid,
           row_number() over (partition by col1, col2 order by rowid) rownumber
    from   my_table
    )
  where rownumber > 5
  )
/

【讨论】:

  • +1。谢谢大卫。我会选择文森特的解决方案。即使你的看起来优雅而简单。 :)
【解决方案2】:

这将删除除满足 Col1 和 Col2 两个条件的 20 行之外的所有行:

DELETE FROM tableA
 WHERE ROWID NOT IN (SELECT ROWID
                       FROM tableA
                      WHERE col1 = someCondition
                        AND col2 = someOtherCondition
                        AND rownum <= 20)

如果你的数据集真的很大,下面的可能会更快:

CREATE tableTemp as 
SELECT *
  FROM tableA
 WHERE col1 = someCondition
   AND col2 = someOtherCondition
   AND rownum <= 20;

TRUNCATE tableA;

INSERT INTO tableA (SELECT * FROM tableTemp);

如果您需要在操作期间访问数据,请将截断替换为 DELETE。

【讨论】:

  • +1。谢谢文森特。在接受您的回答之前,我只是在等待其他选项。
【解决方案3】:

这将使每组最多保留 5 个:

delete mytable where rowid in
( select rowid from
  ( select rowid, row_number() over (partition by col1, col2 order by id) rn
    from mytable
  )
  where rn > 5
);

【讨论】:

    【解决方案4】:

    ROWNUM>5 不起作用,因为对于第一个受影响的行,ROWNUM 始终为 1;此条件还包括“ROWNUM>5”部分,因此 Oracle 不可能找到符合要求的行。

    这可能有效:

    delete from tableA
     --- I can decide on the rows to delete based on two conditions.
     where col1 = someCondition
       and col2 = someOtherCondition
       and rownum <= (select count(*) from tableA 
                        where col1 = someCondition
                          and col2 = someOtherCondition) - 5;
    

    【讨论】:

      【解决方案5】:

      在表中保留任意 500 行并删除其余行。

      delete from tablenameX where rownum <= (select count(*) - 500 from tablenamex);
      

      仅当行数较少时才建议使用上述 sql。如果较大,则使用前面建议的方法来创建临时表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        • 2021-12-30
        • 2018-02-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 2010-09-13
        相关资源
        最近更新 更多