知识卡片
区间变元的精确定义与"相关名称不是别名"的严重误称
内容
[[关系演算的基本结构区间变元原型元组WHERE谓词]]里已引入区间变元概念,本节
落实到SQL的具体机制:SQL通过FROM或显式JOIN上下文中的AS声明来定义区间变元,
比如FROM S AS SX让SX成为覆盖表S的区间变元——整个SELECT表达式的求值可以
理解为:区间变元依次取表S的每一行作为自己当前的允许值,检验对应的条件,
满足则把结果计入输出,直到遍历完S的所有行。SQL要求SELECT表达式总是要以
区间变元的方式表述,如果没有显式声明,SQL会假设存在一个和对应表同名的
隐式区间变元——SELECT SNO FROM S WHERE STATUS>15本质上是
SELECT S.SNO FROM S AS S WHERE S.STATUS>15的简写,这里第二个”S”(点
限定符和AS声明里的S)代表的不是表S本身,而是覆盖表S的、名为S的区间变元,
两者在概念上是完全不同的东西。SQL标准把这类AS引入的名称称为”相关名称”
(correlation name),但书中提出一个措辞层面的强烈反对:大量SQL文档把
区间变元名称说成”别名”(alias),并把它描述成”所覆盖表的一个可选名字”——
这个说法严重歪曲了事实,因为它把一个逻辑意义上的变量(区间变元,有自己
独立的语义角色,覆盖某个特定的元组集合)矮化成了”表的另一个称呼”这种纯粹
的命名便利,暴露了对区间变元真实本质的严重认知缺失。区间变元定义之后还
可以(可选地)附带一份列名重命名列表,但这个语法要求要么全部列都重新
命名、要么一个都不改,不支持只对部分列重命名——如果已经遵循本书列命名
方面的一贯建议,实践中通常不需要用到这个选项。实践建议是养成显式声明区间
变元的习惯(尤其在复杂表达式里),因为SQL围绕这类变量的作用域规则本身
相当难懂,不管变量是显式声明还是隐式假设的都是如此。