SQL连接实际上如何工作?

时间:2015-12-08 06:41:34

标签: mysql sql join computer-science

假设我有两个表Gardners tablePlantings table

enter image description here

假设我的查询是:

SELECT gid, first_name, last_name, pid, gardener_id, plant_name 
FROM Gardners
INNER JOIN Plantings
ON gid = gardener_id

我想知道它内部是如何运作的?

根据我对每个join条件的理解:

  • Gardner Table的每一行都会与Plantings Table的每一行进行比较。如果条件匹配则会打印出来。我的理解是否正确?

如果您认为,在计划方面:

for i in [Gardners Table]:
    for j in [Plantings Table]:
         if i.id == j.garderner id:
            print <>

现在假设您查询的内容如下:

User(uid,uname,ucity,utimedat)
Follows(uid,followerid) // uid and followerid are pointing to `uid` of `User`.

SELECT U.uid, U.uname FROM User U1 JOIN Follows F,User U2 WHERE 
  F.followerid = U2.uiddate AND U2.ucity = 'D'

连接条件如何在内部工作?它等同于:

for i in [USER]:
        for j in [Follows]:
            for k in [USER]:
             if condition:
                print <>

3 个答案:

答案 0 :(得分:2)

Gardners tablePlantings table的示例是正确的。但users的例子并不那么明显。

我认为您想要获得的是来自某个城市的用户关注者。

假设正确的查询是:

SELECT U1.uid, U2.uname
FROM User U1 
  JOIN Follows F ON U1.uid = F.uid
  JOIN User U2 ON F.followerid = U2.uid
WHERE U2.ucity = 'D'

然后在伪代码中它看起来像这样:

for i in [User Table]:
  for j in [Follows Table]:
    if i.uid = j.uid:
      for k in [User Table]:
        if j.followerid = k.uid and k.city = 'D':
          print <>

SQL小提琴:http://sqlfiddle.com/#!9/caeb1e/5

有一个关于联接实际如何工作的非常好的图片可以在这里找到:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

SQL Joins

答案 1 :(得分:1)

在你的第二个查询中,由于语法错误,你不清楚你要做什么。但是,如果我猜测,似乎你的意图是加入用户U1与追随者F和用户U2之间的(隐式)联接的子查询。

如果我的猜测是正确的,那么查询看起来会更像这样:

SELECT U1.uid, U1.uname 
FROM User U1 JOIN 
  (SELECT U2.uid 
   FROM Followers F,User U2 
   WHERE F.followerid = U2.uiddate AND U2.ucity = 'D') T 
WHERE u1.uid = T.uid

这也不是编写查询的“最佳实践”方式(您应该使用显式连接,不需要子查询,但您可以加入三次,依此类推) 但是我这样写它是为了使它最接近原始查询。

如果我的猜测是正确的,那么你的伪代码会更像:

for u2 in [User 2 where condition]:
        for f in [Follows]:
           if f.uid == u2.uid
             SELECT uid AS T
               for u1 in [User 1]:
                 if u1.uid == T.uid:
                   print <>

然而,这不是一个完全解释的解释,因为理解SQL的一个关键是在被过滤的数据的“集合”中考虑更多,而不是顺序选择数据对象,因为SQL根据数据集进行操作,哪一个可能不习惯。 因此,上述一些步骤将一次性执行,而不是顺序执行。但除此之外,你应该看看上面的Yuri Tkachenko给出的答案,如何查看连接 - 然后在编写正确的连接时内部将成为第二。

答案 2 :(得分:0)

是的,如果你只是谈论一个连接而不是另一个连接,你的理解是正确的,例如:内部,外部就像在SQL中