我正在尝试从我提供place_id的map_points表中删除行,但只有在place_id不是为同一map_id输入的另一个place_id的祖先时才删除
CREATE TABLE map_points {
map_id int,
place_id int
}
CREATE TABLE place_relation {
ancestor int,
child int
}
| map_id | place_id |
+--------+----------+
| 10 | 20 |
| 10 | 22 |
| 12 | 20 |
| 12 | 31 |
| 12 | 21 |
| 13 | 20 |
| 13 | 44 |
| 14 | 33 |
| 14 | 31 |
| 14 | 20 |
| 14 | 44 |
+--------+----------+
| ancestor | child |
+----------+-------+
| 20 | 22 |
| 20 | 21 |
| 31 | 33 |
+----------+-------+
我想删除place_id = 20的map_points,但是如果该地方在place_relation表中有子节点则不会。执行删除后,结果集应如下所示。
| map_id | place_id |
+--------+----------+
| 10 | 20 |
| 10 | 22 |
| 12 | 20 |
| 12 | 31 |<- deleted
| 12 | 21 |
| 13 | 20 |<- deleted
| 13 | 44 |
| 14 | 33 |
| 14 | 31 |
| 14 | 20 |<- deleted
| 14 | 44 |
+--------+----------+
这是我所处的位置,但它删除了太多记录
DELETE p
FROM map_points p
JOIN place_relation r ON r.ancestor = p.place_id
LEFT JOIN map_points p2 ON p2.map_id = p.map_id AND p2.place_id = r.child
WHERE p.place_id IN ( 20, 31 )
AND p2.place_id IS NULL
修改
我已从LEFT JOIN中删除了其中一个条件,但现在没有删除任何内容
DELETE p
FROM map_points p
JOIN place_relation r ON r.ancestor = p.place_id
LEFT JOIN map_points p2 ON p2.place_id = r.child
WHERE p.place_id IN ( 20, 31 )
AND p2.place_id IS NULL
修改
根据原始标准,以下查询会给出正确的结果
DELETE p
FROM map_points p
JOIN place_relation r ON r.ancestor = p.place_id
LEFT JOIN map_points p2 ON p2.map_id = p.map_id AND p2.place_id IN (
SELECT child
FROM place_relation
WHERE r.ancestor = ancestor
)
WHERE p.place_id IN ( 20, 31 )
AND p2.place_id IS NULL
已更新
在处理查询时,我通过添加更准确地反映活动数据库中数据的行来更新place_relation表。
| ancestor | child |
+----------+-------+
| 20 | 22 |
| 20 | 21 |
| 21 | 22 |*
| 31 | 33 |
+----------+-------+
期望的最终结果
| map_id | place_id |
+--------+----------+
| 10 | 20 |
| 10 | 21 |* // all ancestors are added to map_points table
| 10 | 22 |
| 12 | 20 |<- deleted
| 12 | 31 |<- deleted
| 12 | 21 |<- deleted
| 13 | 20 |<- deleted
| 13 | 44 |
| 14 | 33 |
| 14 | 31 |
| 14 | 20 |<- deleted
| 14 | 44 |
+--------+----------+
然后在WHERE标准中添加21 ... 在哪里p.place_id IN(20,21,31)
生成的DELETE没有从map_points表中删除行(12,20)。
因此,看起来这个查询只能在WHERE标准中取一个值。因此,在删除语句一次执行一个值之前,需要对数据进行排序。
有没有办法编写查询,以便可以在WHERE标准中输入多个值?
已更新
要获得具有多个值的所需结果,似乎我必须在子选择中输入多个值
DELETE p
FROM map_points p
JOIN place_relation r ON r.ancestor = p.place_id
LEFT JOIN map_points p2 ON p2.map_id = p.map_id AND p2.place_id IN (
SELECT child
FROM place_relation
WHERE r.ancestor = ancestor
AND child NOT IN (20,21,31)
)
WHERE p.place_id IN (20,21,31)
AND p2.place_id IS NULL
答案 0 :(得分:0)
-moz-user-select: none;
中有太多条件:
left join
基本上,您的条件限制性太强,因此DELETE p
FROM map_points p JOIN
place_relation r
ON r.ancestor = p.place_id LEFT JOIN
map_points p2
ON p2.place_id = r.child
WHERE p.place_id IN ( 20, 31 ) AND p2.place_id IS NULL;
中的记录无法匹配。因此,最终条件p2
通常是正确的 - 并且将删除太多记录。