我试图从SQL中的表表中删除多行。问题是我无法弄清楚如何使用子查询的结果从该表中删除,因为该表中没有主键。表的结构如下:
Friend ( ID1, ID2 )
ID1
的学生与ID2
的学生是朋友。友谊是相互的,所以如果(123, 456)
在朋友表中,那么(456, 123)
也是如此。
Likes ( ID1, ID2 )
ID1
的学生喜欢ID2
的学生。喜欢某人不一定是相互的,所以如果在{Likes}表中(123, 456)
,则无法保证(456, 123)
也存在。
(No primary key)
我想解决的问题是:
“如果两个学生A和B是朋友,而A喜欢B但反之亦然,请删除Likes元组。”
提前致谢。
答案 0 :(得分:1)
在大多数SQL方言中,您可以这样做:
delete from likes
where not exists (select 1 from likes l2 where l2.id1 = likes.id2 and l2.id2 = likes.id1) and
exists (select 1 from friends f where f.id1 = likes.id1 and f.id2 = likes.id2);
这几乎是你的两个条件的直接翻译。
答案 1 :(得分:1)
要解决您的问题,请使用以下sql查询
delete from friend where (ID1,ID2) not in
(Select f1.ID1,f1.ID2 from friend f1, friend f2 where f1.ID1 = f2.ID2 && f1.ID2 = f2.ID1)
如果您的数据库不支持“in”子句中的mulitple列,则使用以下查询
delete from friend where concat(ID1,':',ID2) not in
(Select concat(f1.ID1,':',f1.ID2) from friend f1, friend f2
where f1.ID1 = f2.ID2 && f1.ID2 = f2.ID1)
我们可以将ID1和ID2的组合视为复合主键吗?
最好始终在每个表中使用主键。 请使用整数自动增量字段将主键添加到表中,这将很容易解决您的问题
答案 2 :(得分:1)
非常有趣的问题: -
在这里我创建你的表并尝试创建相同的场景,我找到了解决方案。 愿它帮助你...
CREATE TABLE friends
(
id1 NUMERIC,
id2 NUMERIC
);
CREATE TABLE likes
(
id1 NUMERIC,
id2 NUMERIC
);
INSERT INTO friends
VALUES (1,
2);
INSERT INTO friends
VALUES (2,
1);
INSERT INTO friends
VALUES (1,
3);
INSERT INTO friends
VALUES (3,
1);
INSERT INTO friends
VALUES (3,
2);
INSERT INTO friends
VALUES (2,
3);
INSERT INTO likes
VALUES (1,
2);
INSERT INTO likes
VALUES (2,
1);
INSERT INTO likes
VALUES (1,
3);
INSERT INTO likes
VALUES (3,
1);
INSERT INTO likes
VALUES (2,
3);
SELECT *
FROM friends
SELECT *
FROM likes
SELECT *
FROM likes A
WHERE NOT EXISTS (SELECT 1
FROM likes B
WHERE A.id1 = B.id2
AND A.id2 = B.id1
AND EXISTS (SELECT 1
FROM friends
WHERE A.id1 = friends.id1
AND A.id2 = friends.id2));
您的删除查询将是......
DELETE A
FROM likes AS A
WHERE NOT EXISTS (SELECT 1
FROM likes B
WHERE A.id1 = B.id2
AND A.id2 = B.id1
AND EXISTS (SELECT 1
FROM friends
WHERE A.id1 = friends.id1
AND A.id2 = friends.id2));
答案 3 :(得分:0)
我试图为这个问题找到答案。它适用于我的小测试数据,但是请指出它对于更大的数据是否效率低,或者如何通过更好的解决方案使其更好。
Delete from Likes where
ID1 in (select Q.ID1
from (select x.ID1, x.ID2
from (select A.ID1,A.ID2,B.ID2 as se
from Likes A left join Likes B
on A.ID2=B.ID1) x where x.ID1 <> x.se or x.se is null) Q inner join Friend F
where Q.ID1 = F.ID1 and Q.ID2 = F.ID2 order by Q.ID1)
and ID2 in (select Q.ID2
from (select x.ID1, x.ID2
from (select A.ID1,A.ID2,B.ID2 as se
from Likes A left join Likes B
on A.ID2=B.ID1) x where x.ID1 <> x.se or x.se is null) Q inner join Friend F
where Q.ID1 = F.ID1 and Q.ID2 = F.ID2 order by Q.ID1)
答案 4 :(得分:0)
通过连接将两列表示为一个值,然后使用反向组合的NOT IN ()
:
delete from likes
where id1 || ' ' || id2 not in (select id2 || ' ' || id1 from likes);
在SQLFiddle上查看live demo,显示此查询确实有效。