社交网络查询之间的差异

时间:2014-09-26 02:21:13

标签: sql mysql database

这来自斯坦福Coursera自学DB课程SQL测验:

  

你家乡高中的学生决定组织他们的   社交网络使用数据库。到目前为止,他们收集了   有关十六名学生的信息,分为四个等级,9-12。这是   架构:

Highschooler (ID, name, grade) 
     

英语:有一个高中生有唯一的ID和给定的   某个年级的名字。

Friend (ID1, ID2) 
     

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

Likes (ID1, ID2) 
     

英语:ID1的学生喜欢ID2的学生。喜欢   某人不一定是相互的,所以如果(123,456)在喜欢中   表,不保证(456,123)也存在。

     

数据库   here

     

提示:对于每个学生A喜欢学生B,两个人不是朋友,找出他们是否有一个共同的朋友C(谁可以介绍   他们!)。对于所有这些三重奏,请返回A,B和C的名称和等级。

我有一个生成正确结果的查询,以及一个生成错误结果的查询,但我无法从逻辑上弄清楚为什么以下查询不正确。我已经加粗了引起问题的问题,但我很难通过思考并希望进行简短的代码审查。

由于条款and b.id not in (select id2 from friend where a.id=id1)而导致的工作查询:

select distinct a.name, a.grade, b.name, b.grade, c.name, c.grade
from highschooler a, highschooler b, highschooler c, likes, friend
where a.id=likes.id1
and b.id=likes.id2
and a.id=friend.id1
-- this next line
and b.id not in (select id2 from friend where a.id=id1)
and b.id in (select id1 from friend where id2=c.id)
and a.id in (select id1 from friend where id2=c.id)

由于条款and b.id <>friend.id2而导致查询不正确:

select distinct a.name, a.grade, b.name, b.grade, c.name, c.grade
from highschooler a, highschooler b, highschooler c, likes, friend
where a.id=likes.id1
and b.id=likes.id2
and a.id=friend.id1
-- as opposed to this one
and b.id <>friend.id2
and b.id in (select id1 from friend where id2=c.id)
and a.id in (select id1 from friend where id2=c.id)

查询1结果:

Andrew 10 Cassandra 9 Gabriel 9

Austin 11 Jordan 12 Andrew 10

Austin 11 Jordan 12 Kyle 12

查询2结果:

Andrew 10 Cassandra 9 Gabriel 9

Brittany 10 Kris 10 Haley 10

Austin 11 Jordan 12 Andrew 10

Austin 11 Jordan 12 Kyle 12

Gabriel 11 Alexis 11 Jessica 11

2 个答案:

答案 0 :(得分:2)

这两个条件具有非常不同的含义:

--1
and b.id not in (select id2 from friend where a.id=id1)
--2
and b.id <> friend.id2

假设b.idjackselect id2 from friend where a.id=id1为:

id2
---
alice
bob

在第一个查询中,对于表jack中的b行,您实际上有条件“jack不是(alice,bob)之一”。这产生了真,因此该行将包含在输出中。

在第二个查询中,对于表jack中的b行,您实际上是在尝试加入friendid2不在jack {1}}。在我们的示例中,有2条此类记录,一条记录为alice,另一条记录为bob。因此,在输出中,您将获得jack的2条记录,一条用于alice,另一条用于bob

在第一个查询中,您或者从jack获取b的记录。在第二个查询中,您获得n的{​​{1}}条记录,其中jackn不是id2的记录数。如果所有记录都是jack,那么您将不会从jack获得任何记录。完全不同的东西。

答案 1 :(得分:-1)

您的问题似乎主要来自于使用ANSI-89 join而不是使用现代显式join。如果您使用了现代join s,则可以更轻松地进行故障排除。

您的第一个版本正在制作现在称为inner join的版本,而您的第二个版本正在寻找&#34;不等于&#34;。这就是你得到不同结果的原因。