【问题标题】:SQL Query I'm having trouble with我遇到问题的 SQL 查询
【发布时间】:2013-02-16 21:19:26
【问题描述】:

我有这些表:

高中生(ID、姓名、年级) 在某个年级有一个具有唯一 ID 和给定名字的高中生。

朋友(ID1,ID2) ID1 的学生与 ID2 的学生是朋友。友谊是相互的,所以如果 (123, 456) 在 Friend 表中,那么 (456, 123) 也是。

喜欢(ID1,ID2) ID1 的学生喜欢 ID2 的学生。喜欢某人不一定是相互的,因此如果 (123, 456) 在 Likes 表中,则不能保证 (456, 123) 也存在。

如果两个学生 A 和 B 是朋友,并且 A 喜欢 B 但反之不喜欢,我想删除 Likes 元组。

首先,我尝试只获取 2 个不互惠的喜欢的元组,但我没有成功...

我有这个:

SELECT * 
FROM Likes
where Likes.ID1 in (
   select Likes.ID1 
   from Likes, Friend
   where Likes.ID1=Friend.ID1 
     and Likes.ID2=Friend.ID2
   ) 
AND NOT IN (
   SELECT Likes.ID1 
   FROM Likes L1, Likes L2, Friend
   WHERE L1.ID1=Friend.ID1 
     AND L2.ID2=Friend.ID2 
     AND L1.ID1 = L2.ID2 
     AND L1.ID2 = L2.ID1);

但它不起作用..我收到一个错误..有人可以帮我解决这个问题吗!

我实际上有一张带有值的表格的图像,但我无法发布它,因为我需要超过 10 个声望才能做到这一点......

编辑:

好的,我要把表格放在这里,因为我仍然没有得到正确的结果

Highschooler
ID  name    grade
1510    Jordan  9
1689    Gabriel 9
1381    Tiffany 9
1709    Cassand 9
1101    Haley   10
1782    Andrew  10
1468    Kris    10
1641    Brit    10
1247    Alexis  11
1316    Austin  11
1911    Gabriel 11
1501    Jessica 11
1304    Jordan  12
1025    John    12
1934    Kyle    12
1661    Logan   12


Friend
ID1 ID2
1510    1381
1510    1689
1689    1709
1381    1247
1709    1247
1689    1782
1782    1468
1782    1316
1782    1304
1468    1101
1468    1641
1101    1641
1247    1911
1247    1501
1911    1501
1501    1934
1316    1934
1934    1304
1304    1661
1661    1025
1381    1510
1689    1510
1709    1689
1247    1381
1247    1709
1782    1689
1468    1782
1316    1782
1304    1782
1101    1468
1641    1468
1641    1101
1911    1247
1501    1247
1501    1911
1934    1501
1934    1316
1304    1934
1661    1304
1025    1661

Likes
ID1 ID2
1689    1709
1709    1689
1782    1709
1911    1247
1247    1468
1641    1468
1316    1304
1501    1934
1934    1501
1025    1101

我应该最终从 likes 表中删除这 2 个元组: 1911-1247 1641-1468

他们是互惠互利的朋友,也是朋友

【问题讨论】:

  • 你用的是mysql还是sqlite?
  • 你的意思是“如果两个学生 A 和 B 是朋友,并且 A 喜欢 B 但反之不喜欢,我想删除朋友元组。”?
  • 使用EXISTS,你就不会再犯这个错误了
  • 我试过了,但没有用。我编辑了我的帖子以包含带有实际值和预期结果的表格
  • 你能为此创建一个 Sqlfiddle - sqlfiddle.com

标签: sql database sqlite


【解决方案1】:

由于您正在为这个问题学习斯坦福 SQL 入门课程,因此我将提供我的工作答案。提到它必须在 SQlite 中工作是一个好主意。我是 SQL 的初学者,我很确定有一个更优雅的解决方案,但这应该通过自动化测试。这是我的解决方案:

DELETE FROM likes
WHERE likes.id1 in (Select s1.id
FROM highschooler s1, highschooler s2, friend, likes
WHERE s1.id <> s2.id
  AND friend.id1 = s1.id 
  AND friend.id2 = s2.id
  AND likes.id1 = s1.id 
  AND likes.id2 = s2.id
  AND s2.id NOT IN (SELECT s3.id FROM likes, highschooler s3, highschooler s4
                    WHERE s3.id = s2.id 
                        AND s4.id = s1.id
                        AND s3.id <> s4.id 
                        AND likes.id1 = s3.id 
                        AND likes.id2 = s4.id))

【讨论】:

    【解决方案2】:

    试试这个

      SELECT * 
     FROM Likes
     where Likes.ID1 in 
                   (select Likes.ID1 from Likes, Friend where Likes.ID1=Friend.ID1 and Likes.ID2=Friend.ID2) 
      AND Likes.ID1 NOT IN (SELECT Likes.ID1 FROM Likes L1, Likes L2, Friend WHERE L1.ID1=Friend.ID1 AND L2.ID2=Friend.ID2 AND L1.ID1 = L2.ID2 AND L1.ID2 = L2.ID1);
    

    【讨论】:

    • 我试过了,但没有用。我编辑了我的帖子以包含带有实际值和预期结果的表格——
    【解决方案3】:

    您的错误是因为您需要在第二个 AND 条件中重复 Likes.ID1 字段。

    SELECT * 
    FROM Likes
    where Likes.ID1 in (select Likes.ID1
                        from Likes, Friend
                        where Likes.ID1=Friend.ID1 and Likes.ID2=Friend.ID2)
      AND Likes.ID1 NOT IN (SELECT Likes.ID1
                 FROM Likes L1, Likes L2, Friend
                 WHERE L1.ID1=Friend.ID1
                   AND L2.ID2=Friend.ID2
                   AND L1.ID1 = L2.ID2
                   AND L1.ID2 = L2.ID1);
    

    我没有分析您的查询是否会返回正确的结果。不过,这可能,

    select *
    from Likes L1
      inner join Friend on L1.ID1 = Friend.ID1
      left outer join Likes L2 on Friend.ID2 = L2.ID1 and L1.ID1 = L2.ID2
    where L2.ID2 is null
    

    【讨论】:

    • 我试过了,但没有用。我编辑了我的帖子以包含带有实际值和预期结果的表格
    • 好吧,我希望你能看到这个想法。首先找到所有喜欢的。然后找到所有喜欢的朋友。然后搜索所有朋友喜欢的人,包括这次丢失的结果。然后是 where 子句,仅返回缺少最后一个喜欢的结果。
    【解决方案4】:

    虽然这不是在您的查询中准确找到错误,但我会这样做:

    SELECT * 
    FROM Likes L1
    WHERE
    EXISTS ( -- friendship exists
       SELECT *
       FROM Friends F 
       WHERE  F.ID1 IN (L1.ID1, L1.ID2) AND F.ID2 IN (L1.ID1, L1.ID2)
    )
    AND NOT EXISTS ( -- reverse like does not exist
       SELECT *
       FROM Likes L2
       WHERE L1.ID1  = L2.ID2 AND L1.ID2 =  L2.ID1
    );
    

    注意ALikesFriends中的朋友AB的顺序可能不同,所以我们需要像我一样使用INOR声明JOIN

    【讨论】:

    • 我试过了,但没有用。我编辑了我的帖子以包含带有实际值和预期结果的表格
    猜你喜欢
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    相关资源
    最近更新 更多