SQL 连接实际上是如何工作的?

How the SQL join actually works?

假设我有两个 table Gardners tablePlantings table.

假设我的查询是:

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

我想知道它在内部究竟是如何工作的?

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

在程序方面如果你认为:

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 <>

是的,如果您只是在谈论一个联接而不是另一个联接,那么您的理解是正确的,例如:内部,外部,如 SQL

您使用 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 Fiddle 为此:http://sqlfiddle.com/#!9/caeb1e/5

可以在此处找到关于联接实际工作原理的非常好的图片:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

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

如果我的猜测是正确的,查询应该更像这样:

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

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

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

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 的一个关键是在 'set' 中更多地思考被过滤的数据,而不是数据对象的顺序选择,因为 SQL根据一组数据进行运算,大家可能不习惯。 所以上面的一些步骤将一次性执行,而不是顺序执行。但除此之外,您应该查看上面 Yuri Tkachenko 给出的关于如何查看连接的答案——然后在编写正确的连接时,内部结构将排在第二位。