1

我在使用显式连接理解正确的 sql 语法时遇到问题。例如在第一个片段中,在第二个连接中“ec”是可见的并且限制有效。但在第二个片段中,“op”无法解决。

第一个片段:

select im.* 
  from gestion_corte gc 
  join evento_corte ec
       on ec.id_corte = gc.id_corte
  join op_corte op
       on op.id_corte = gc.id_corte
       and op.fecha_evento = ec.fecha_evento        
  join img_corte im        
       on op.id_corte = im.id_corte                     
 where ec.fecha_evento > '01092012'  

第二个片段,“op”在第一次加入时无法解析:

select im.* 
  from gestion_corte gc 
  join evento_corte ec
       on ec.id_corte = gc.id_corte
       and op.fecha_evento = ec.fecha_evento -- This condition has moved
  join op_corte op
       on op.id_corte = gc.id_corte        
  join img_corte im        
       on op.id_corte = im.id_corte                     
 where ec.fecha_evento > '01092012'

结果,可见性是从上到下解决的处理吗?还有其他重要的事情需要考虑吗?

4

3 回答 3

2

在 SQL 连接语法中,别名在定义之前是未知的。所以,你可以这样做:

from A a join
     B b
     on a.val = b.val join
     C c
     on a.val = c.val

但是,您不能这样做:

 from A a join
     B b
     on a.val = b.val and
        a.id = c.id join
     C c
     on a.val = c.val

fromSQL 引擎根本不知道“c”是什么,因为在语句中还没有看到“c” 。

正如您所发现的,您的第二个查询很容易通过移动条件来修复。

于 2012-11-16T17:09:16.617 回答
2

连接是在两个虚拟表之间。

连接谓词只能引用这两个虚拟表中的列(尽管每个虚拟表可能包含来自多个基表的列)。

有效使用的顺序不一定是自上而下的,因为逻辑连接顺序是由ON子句的顺序决定的。因此,例如在以下查询(SQL Fiddle)中,虚拟表(a join b)连接到虚拟表(c join d join e)

SELECT *
FROM   a
       JOIN b
         ON a.id = b.id /*Only a and b in scope here*/
       JOIN c
            JOIN d
              ON c.id = d.id /*Only c and d in scope here*/
            JOIN e
              ON e.id = d.id /*Only c, d, e in scope here*/
         ON d.id = a.id  /*a,b,c,d,e all in scope*/

此查询(SQL Fiddle)会给出一个错误,因为a它不在范围内。

SELECT *
FROM   a
       JOIN b
         ON a.id = b.id
       JOIN c
            JOIN d
              ON c.id = d.id
            JOIN e
              ON e.id = a.id -- Can't reference a here
         ON d.id = a.id 
于 2012-11-16T19:52:27.287 回答
0

我没有得到你的第二个问题,所以我只回答第一个问题。
可以这样想象您的连接:

“结果” = 从“任何来源”中选择“某些列”

“任何来源”可以是表或子查询(即另一个“结果”)或“任何来源”连接“任何来源”:
“任何来源”=表| “结果” | “任何来源”加入“任何来源”

所以如果你想要一个“结果”,你应该首先确定“任何来源”然后是“一些列”(我们不要专注于它)。让我们去“任何来源”的定义来确定它。表被确定,“结果”递归地导致前一个句子和连接构造有一个规则 - 确定它首先得到左“任何来源”然后右。

所以,看看你的第二个片段。由于 op_corte 尚未确定,这部分gestion_corte join evento_corte尚未计算

于 2012-11-16T17:17:51.810 回答