【问题标题】:Oracle SQL - Delete Entries Based Off Unique RowsOracle SQL - 根据唯一行删除条目
【发布时间】:2018-04-25 14:02:38
【问题描述】:

我正在从数据库中提取一列,它看起来像这样:

Group
A
A
A
B
B
B
C
D
D
D
E
F
F
F

我需要删除唯一的条目,所以条目 A、B、D 和 F 应该保留,条目 C 和 E 应该被删除。

我根据这样的查询得到这一行:

select Group from table where type = 'rec';

基本上每种类型都应该有多个组,如果没有,则需要将其删除。

注意:我需要它是自动化的,而不仅仅是“删除 C”和“删除 E”,因为有数千行,除非我找到它们,否则我不确定需要删除哪些。需要删除的行数也会发生变化,因此我需要根据计数自动执行它。

【问题讨论】:

  • 基本上你想删除字符串中的所有唯一字符?
  • 我想删除只出现一次的组。每个组都需要多个条目才能起作用,因此需要删除从我的 select 语句中只出现一次的任何组。
  • 您是否需要将它们从基础表中实际删除,还是只需要它们不出现在您的SELECT 语句中?

标签: sql oracle


【解决方案1】:

一种方法是:

delete t
    where "group" in (select "group" from t group by "group" having count(*) = 1);

根据您的示例代码:

delete t
    where type = 'rec' and
          "group" in (select "group" from t where type = 'rec' group by "group" having count(*) = 1);

你也可以这样做:

delete t
    where type = 'rec' and
          not exists (select 1
                      from t t2
                      where t2.group = t.group and t2.type = 'rec' and t2.rowid <> t.rowid
                     );

【讨论】:

    【解决方案2】:

    根据您的 cmets 判断,您所需要的只是总计。如果条目发生一次,则选择/删除它。如果您问我,分析函数是最好和最简单的方法:

    SELECT * FROM 
    (
     SELECT COUNT(grp) OVER (PARTITION BY grp ORDER BY grp) cnt -- number of occurances --
           , grp 
       FROM
       ( -- convert to multi-row - REPLACE AAABBB with your actual column --
        SELECT trim(regexp_substr('A A A B B B C D D D E F F F', '[^ ]+', 1, LEVEL)) grp
          FROM dual -- from your table_name --
        CONNECT BY LEVEL <= regexp_count('A A A B B B C D D D E F F F', '[^ ]+')
       )
      )
     WHERE cnt = 1 -- Select/Delete only those that appeared once -- 
     /
    

    输出:

    cnt|grp
    --------
    1   C
    1   E
    

    完整输出,如果你在哪里评论:

    cnt|grp
    --------
    3   A
    3   A
    3   A
    3   B
    3   B
    3   B
    1   C
    3   D
    3   D
    3   D
    1   E
    3   F
    3   F
    3   F
    

    根据您的问题进行最终编辑。这模拟了您的桌子:

    WITH your_table AS
    (
     SELECT 'rec' grp_type FROM dual
     UNION ALL
     SELECT 'not_rec' grp_type FROM dual
     )
     SELECT grp_type FROM your_table WHERE grp_type = 'rec' -- apply all that above to this select --
     /
    

    【讨论】:

    • 有没有办法用select语句有效地替换查询中的'A A A B B B C D D D ...'字符串?我试图只是更换,它没有工作
    • @M.罗杰斯 - 如果您的问题是针对我的,那么我不确定我是否理解您的意思。例子?
    • 是的。 A A A B B B C D D... 的输出是“select Group from table where type = 'rec';”的结果有没有办法用字符串替换 A A A B B C D D 的字符串?我试图替换它,但它破坏了功能
    • @M.罗杰斯 - 字符串意味着在输出周围加上引号?这是你需要的 - 'A A A B B B C D D ...'?
    • 我该怎么做:SELECT trim(regexp_substr(select Group from table where type = 'rec';, '[^ ]+', 1, LEVEL)) str FROM dual CONNECT BY LEVEL
    猜你喜欢
    • 2020-07-15
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多