为什么在连接条件下使用实际表名对表和质量进行别名时,会出现“Out of spool”错误?
例如; sel name,来自emp_table E的ID 内部联接 dep_table D. 上 emp_table.dep_no = D.dep_no
答案 0 :(得分:2)
当您使用“真实”表名进行限定时,Teradata并不认为您指的是与别名相同的表格实例。因此,它是交叉连接emp_table
的另一个实例(在您的示例中),它必须为您的安装生成太多数据才能处理。 (即使它完成了,它也会得到意想不到的结果,因为逻辑根本没有说出你的意思;见下文。)
如果您考虑一下,DBMS将走向一条危险的道路,假设emp_table.dep_no
引用与E.dep_no
相同的表格实例;那么它将如何处理这个问题:
SELECT e.id
FROM emp_table e
inner join emp_table m
on e.manager_id = m.id
WHERE emp_table.dep_num = 37
但我不喜欢它的行为方式。 IMO它应该抛出一个错误,因为你的FROM
子句没有指定任何要表示为emp_table
的表。唉,Teradata通常只是通过引用它们来允许隐式连接到新的表实例。
所以我提到即使查询完成,你也会得到意想不到的结果。考虑一个包含小数据集的示例:
EMP_TABLE
-----------------------------
EMP_ID | DEPT_ID | NAME
1 | A | Sue
2 | B | Bob
DEPT_TABLE
------------------------------
DEPT_ID | NAME
A | Engineering
B | Sales
C | Legal
好的,所以说你只想列出员工及其部门的名字:
select e.name, d.name
from emp_table e
inner join dept_table d
on d.dept_id = e.dept_id
这很好,但现在你决定将员工排除在销售之外。但是您使用实际的表名而不是d
...
select e.name, d.name
from emp_table e
inner join dept_table d
on d.dept_id = e.dept_id
where dept_table.name <> 'Sales'
现在您希望看到Sue | Engineering
。但实际上你会得到四条记录:两条记录Sue | Engineering
,两条记录Bob | Sales
。那是什么给出了什么?
好吧,Teradata认为你的查询意味着
select e.name, d.name
from emp_table e
inner join dept_table d
on d.dept_id = e.dept_id
cross join dept_table x
where x.name <> 'Sales'
正确地关闭了WHERE
过滤器没有按预期应用。 e
和d
除了连接条件之外的行没有任何限制,因此将Sue和Bob保留在结果中。
更糟糕的是,额外关系x
返回了两行,它们与结果集的其余部分交叉连接(这就是为什么你得到每个返回记录的重复)。