【问题标题】:Delete Rows brought back from a Select statement that contains a having and group by clause in Oracle从包含 Oracle 中的 have 和 group by 子句的 Select 语句中删除行
【发布时间】:2025-12-06 02:35:02
【问题描述】:

我有这个选择语句:

SELECT d.idcprefix,
         d.orgdept,
         d.idcseq,
         d.subcont, 
         d.actualcomp, 
         COUNT (*) AS "No Duplicates"
    FROM DCS_IDC, DCS_IDC z
   WHERE     D.IDCPREFIX = z.idcprefix
         AND z.orgdept = d.orgdept
         AND z.idcseq = d.idcseq
         and D.SUBCONT is not null
  HAVING COUNT (*) > 1
GROUP BY d.idcprefix,
         d.orgdept,
         d.idcseq,
         d.subcont,
         d.actualcomp
ORDER BY d.idcprefix,
         d.orgdept,
         d.idcseq,
         d.subcont,
         d.actualcomp

我想删除从该语句中返回的行,有什么想法吗?

Delete FROM 给我一个ORA-01732: data manipulation operation not legal on this view 错误,因为我相信我正在比较两个表,尽管是同一个表。

我还尝试从存在 rowstablename 中删除,但删除的行比我想要的多得多。

“重复”基于 Subcont。使用 subcont 字段将记录插入到数据库/应用程序中,该字段本来是空白的,所以现在我有相同的记录,除了一个记录,例如 subcont 中的 A 和另一个为空白:

idcprefix, subcont, orgdept and idcseq
1          A        ABC         1
1                   ABC         1
2          A        BCD         1
2                   BCD         1

查询显示了所有具有 subcont 的记录,这些记录与没有 subcont 的记录重复,我需要删除具有 subcont 值的记录。

我们将不胜感激!

【问题讨论】:

  • 我的理解是否正确,即此查询在 DCS_IDC 上找到重复项,并且您想删除除一个重复项之外的所有重复项?这个表有主键吗?您是否关心保留了哪些重复项?
  • 您好,该表没有使用主键。该表使用对 idcprefix、subcont、orgdept 和 idcseq 进行约束的唯一键类型。我在上面添加了一些上下文

标签: sql oracle select oracle11g having-clause


【解决方案1】:

假设 (idcprefix, subcont, orgdept, idcseq) 是唯一的,那么下面的呢?

DELETE FROM DCS_IDC
WHERE (idcprefix, subcont, orgdept, idcseq) IN (
  WITH del AS (
  SELECT d.idcprefix,
     d.orgdept,
     d.idcseq,
     d.subcont, 
     d.actualcomp, 
     COUNT (*) AS "No Duplicates"
  FROM DCS_IDC, DCS_IDC z
  WHERE     D.IDCPREFIX = z.idcprefix
     AND z.orgdept = d.orgdept
     AND z.idcseq = d.idcseq
     and D.SUBCONT is not null
  HAVING COUNT (*) > 1
  GROUP BY d.idcprefix,
     d.orgdept,
     d.idcseq,
     d.subcont,
     d.actualcomp
  ORDER BY d.idcprefix,
     d.orgdept,
     d.idcseq,
     d.subcont,
     d.actualcomp
  )
 SELECT idcprefix, subcont, orgdept, idcseq FROM del
)

【讨论】:

  • 您好,该表没有使用主键。该表在 idcprefix、subcont、orgdept 和 idcseq 上使用了唯一的键类型。
  • 感谢 Loannis,这真是一种享受! (你在我添加的 FROM 语句中的第一个 DCS_IDC 之后缺少了一个 D,之后它就完美地工作了!)
【解决方案2】:

怎么样:

BEGIN
  FOR aRow IN (SELECT d.idcprefix,
                      d.orgdept,
                      d.idcseq,
                      COUNT(*) AS DUP_COUNT
                 FROM DCS_IDC d
                 HAVING COUNT(*) > 1
                 GROUP BY d.idcprefix,
                          d.orgdept,
                          d.idcseq)
  LOOP
    DELETE FROM DCS_IDC
      WHERE IDCPREFIX = aRow.IDCPREFIX AND
            ORGDEPT = aRow.ORGDEPT AND
            IDCSEQ = aRow.IDCSEQ AND
            SUBCONT IS NOT NULL;
  END LOOP;
END;

没有保证。使用风险自负。未在动物身上进行测试 - 你会是第一个!

分享和享受。

【讨论】:

  • 谢谢 Bob,我试了一下,但在预期错误的地方找不到 FROM 关键字。我给了 Loannis 一个答案,并且删除了必填字段。
  • SELECT 中的d.idcseq 后面缺少一个逗号。现已修复,物有所值。