SQL:删除使用 3 个连接找到的记录
SQL : Deleting records found using 3 joins
我正在使用 SQL Server 2014 数据库和 SQL Server Management Studio 来创建和 运行 查询。
表格是:
人
| ID | personName |
+----+------------+
| 1 | Hamish |
| 2 | Morag |
| 3 | Ewan |
汽车
| ID | CarName |
+----+---------+
| 1 | Humber |
| 2 | Austen |
| 3 | Morris |
小工具
| ID | GadgetName |
+----+------------+
| 1 | Cassette |
| 2 | CD |
| 3 | Radio |
CarToPersonMap
| ID | CarID | PersonID |
+----+-------+----------+
| 1 | 1 | 1 |
CarToGadgetMap
| ID | CarID | GadgetID |
+----+-------+----------+
| 1 | 2 | 2 |
映射 table 具有适当的外键。
我想删除 Car
存在但未使用的记录。所以在上面的例子中我想用 ID = 3
.
删除 Car
我有一个 SELECT
语句,它使用 3 JOIN
如下。该语句有效并且 returns 正确的行,即 Car
和 ID = 3
.
SELECT *
FROM
(SELECT Cars.*
FROM Cars
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToGadgetMap.CarID IS NULL) t1
JOIN
(SELECT Cars.*
FROM Cars
LEFT JOIN PersonToCarMap ON Cars.ID = PersonToCarMap.CarID
WHERE PersonToCarMap.CarID IS NULL) t2 ON t1.ID = t2.ID
当我使用下面的代码尝试 DELETE
时,它会删除所有 3 Car
行:
DELETE Cars
FROM
(SELECT Cars.*
FROM Cars
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToGadgetMap.CarID IS NULL) t1
JOIN
(SELECT Cars.*
FROM Cars
LEFT JOIN PersonToCarMap ON Cars.ID = PersonToCarMap.CarID
WHERE PersonToCarMap.CarID IS NULL) t2 ON t1.ID = t2.ID
结果信息:
(3 row(s) affected)
并且检查显示 Cars
table 中的所有 3 行已被删除。
为什么 SELECT
语句 returns 只有 1 行时所有记录都被删除?
有人能帮忙吗?
提前致谢
也许使用 WHERE 子句代替 FROM。
DELETE cars WHERE cars.id = 3 (Get your query select only the id from your logic, rather than selecting all the tables with cars.*)
您只需使用此代码即可完成。我在最后创建了一个数据库和数据来测试它。
DELETE Cars
FROM Cars
LEFT JOIN CarToPersonMap ON Cars.ID = CarToPersonMap.CarID
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToPersonMap.CarID IS NULL and CarToGadgetMap.CarID IS NULL
当你执行DELETE
或UPDATE
语句时,要修改的table计算如下:
- 查看
FROM
子句(在 DELETE
中,这是第二个 FROM
),用于使用该名称别名的顶级 table。
- 否则,即使使用别名
,也要查找对 Cars
的单个顶级引用
- 否则将 table
Cars
与整个 FROM
子句交叉连接
你的 DELETE
的问题是顶级作用域没有 table 命名或别名为 Cars
,所以它实际上只是在整个Cars
table.
你也可以这样做
DELETE Cars
WHERE NOT EXISTS (SELECT 1
FROM CarToPersonMap cpm ON Cars.ID = cpm.CarID)
AND NOT EXISTS (SELECT 1
FROM CarToGadgetMap cgm ON Cars.ID = cgm.CarID);
您还可以明确指定第二个 FROM
子句
DELETE Cars
FROM Cars
WHERE ...
我正在使用 SQL Server 2014 数据库和 SQL Server Management Studio 来创建和 运行 查询。
表格是:
人
| ID | personName |
+----+------------+
| 1 | Hamish |
| 2 | Morag |
| 3 | Ewan |
汽车
| ID | CarName |
+----+---------+
| 1 | Humber |
| 2 | Austen |
| 3 | Morris |
小工具
| ID | GadgetName |
+----+------------+
| 1 | Cassette |
| 2 | CD |
| 3 | Radio |
CarToPersonMap
| ID | CarID | PersonID |
+----+-------+----------+
| 1 | 1 | 1 |
CarToGadgetMap
| ID | CarID | GadgetID |
+----+-------+----------+
| 1 | 2 | 2 |
映射 table 具有适当的外键。
我想删除 Car
存在但未使用的记录。所以在上面的例子中我想用 ID = 3
.
Car
我有一个 SELECT
语句,它使用 3 JOIN
如下。该语句有效并且 returns 正确的行,即 Car
和 ID = 3
.
SELECT *
FROM
(SELECT Cars.*
FROM Cars
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToGadgetMap.CarID IS NULL) t1
JOIN
(SELECT Cars.*
FROM Cars
LEFT JOIN PersonToCarMap ON Cars.ID = PersonToCarMap.CarID
WHERE PersonToCarMap.CarID IS NULL) t2 ON t1.ID = t2.ID
当我使用下面的代码尝试 DELETE
时,它会删除所有 3 Car
行:
DELETE Cars
FROM
(SELECT Cars.*
FROM Cars
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToGadgetMap.CarID IS NULL) t1
JOIN
(SELECT Cars.*
FROM Cars
LEFT JOIN PersonToCarMap ON Cars.ID = PersonToCarMap.CarID
WHERE PersonToCarMap.CarID IS NULL) t2 ON t1.ID = t2.ID
结果信息:
(3 row(s) affected)
并且检查显示 Cars
table 中的所有 3 行已被删除。
为什么 SELECT
语句 returns 只有 1 行时所有记录都被删除?
有人能帮忙吗?
提前致谢
也许使用 WHERE 子句代替 FROM。
DELETE cars WHERE cars.id = 3 (Get your query select only the id from your logic, rather than selecting all the tables with cars.*)
您只需使用此代码即可完成。我在最后创建了一个数据库和数据来测试它。
DELETE Cars
FROM Cars
LEFT JOIN CarToPersonMap ON Cars.ID = CarToPersonMap.CarID
LEFT JOIN CarToGadgetMap ON Cars.ID = CarToGadgetMap.CarID
WHERE CarToPersonMap.CarID IS NULL and CarToGadgetMap.CarID IS NULL
当你执行DELETE
或UPDATE
语句时,要修改的table计算如下:
- 查看
FROM
子句(在DELETE
中,这是第二个FROM
),用于使用该名称别名的顶级 table。 - 否则,即使使用别名 ,也要查找对
- 否则将 table
Cars
与整个FROM
子句交叉连接
Cars
的单个顶级引用
你的 DELETE
的问题是顶级作用域没有 table 命名或别名为 Cars
,所以它实际上只是在整个Cars
table.
你也可以这样做
DELETE Cars
WHERE NOT EXISTS (SELECT 1
FROM CarToPersonMap cpm ON Cars.ID = cpm.CarID)
AND NOT EXISTS (SELECT 1
FROM CarToGadgetMap cgm ON Cars.ID = cgm.CarID);
您还可以明确指定第二个 FROM
子句
DELETE Cars
FROM Cars
WHERE ...