使用连接表删除Oracle

时间:2017-10-24 21:22:59

标签: oracle

我有一个包含三列(主键)的表格,我需要一个删除句子,允许我删除我不需要的元素,使用此表和其他表格的连接,我&#39已经尝试了两个删除句子,但它们没有按预期工作:

第一个:这个获取我不需要的值,它们将从表A中删除,但这里的问题是它也删除了表B和C中的值,这些行可以&#39 ; t被删除

DELETE
FROM
  (SELECT A.*
  FROM TABLE_A A
  JOIN TABLE_B B
  ON A.CODE  =B.CODE
  JOIN TABLE_C C
  ON B.PRODUCT           =C.PRODUCT           
  WHERE B.VALUE       >10000
  AND C.RANGE NOT  IN (4006, 4005, 4004, 4003, 4002, 4001)
  );

**第二个:**这个问题是它从表A中删除了所有行,但是如果我测试查询(select)它会返回5行,那些应该删除的行。

DELETE
FROM A WHERE EXIST
  (SELECT A.*
  FROM TABLE_A A
  JOIN TABLE_B B
  ON A.CODE  =B.CODE
  JOIN TABLE_C C
  ON B.PRODUCT           =C.PRODUCT   
  WHERE B.VALUE       >10000
  AND C.RANGE NOT  IN (4006, 4005, 4004, 4003, 4002, 4001)
  );

所以有人知道我可能做错了吗?

1 个答案:

答案 0 :(得分:0)

第一个将删除连接中匹配的行,第二个将删除所有行EXISTS任何一个匹配的行,因为您没有将已删除的行与子查询相关联。

您可以使用ROWID伪列:

执行此关联

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_a ( id, code ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;

CREATE TABLE table_b ( id, code, product, value ) AS
SELECT 1, 1, 1, 10001 FROM DUAL UNION ALL
SELECT 2, 2, 2, 10001 FROM DUAL UNION ALL
SELECT 3, 3, 1,  9999 FROM DUAL;

CREATE TABLE table_c ( id, product, range ) AS
SELECT 1, 1, 1001 FROM DUAL UNION ALL
SELECT 2, 2, 4001 FROM DUAL;

DELETE
FROM table_A
WHERE ROWID IN (
  SELECT A.ROWID
  FROM   TABLE_A A
         JOIN TABLE_B B
         ON A.CODE    = B.CODE
         JOIN TABLE_C C
         ON B.PRODUCT = C.PRODUCT   
  WHERE  B.VALUE >10000
  AND    C.RANGE NOT  IN (4006, 4005, 4004, 4003, 4002, 4001)
);

查询1

SELECT * FROM table_a

<强> Results

| ID | CODE |
|----|------|
|  2 |    2 |
|  3 |    3 |

查询2

SELECT * FROM table_b

<强> Results

| ID | CODE | PRODUCT | VALUE |
|----|------|---------|-------|
|  1 |    1 |       1 | 10001 |
|  2 |    2 |       2 | 10001 |
|  3 |    3 |       1 |  9999 |

查询3

SELECT * FROM table_c

<强> Results

| ID | PRODUCT | RANGE |
|----|---------|-------|
|  1 |       1 |  1001 |
|  2 |       2 |  4001 |