【发布时间】:2020-07-08 03:20:47
【问题描述】:
当我在连接条件中使用真实表名为表和质量设置别名时,为什么会出现“Out of spool”错误?
例如; sel 名称,来自 emp_table E 的 ID 内部联接 dep_table D 上 emp_table.dep_no= D.dep_no
【问题讨论】:
标签: module teradata processor spool
当我在连接条件中使用真实表名为表和质量设置别名时,为什么会出现“Out of spool”错误?
例如; sel 名称,来自 emp_table E 的 ID 内部联接 dep_table D 上 emp_table.dep_no= D.dep_no
【问题讨论】:
标签: module teradata processor spool
当您使用“真实”表名进行限定时,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 返回了两行,它们与结果集的其余部分交叉连接(这就是为什么每个返回的记录都有重复的原因)。
【讨论】: