"Out of spool" Teradata 中的错误
"Out of spool" error in Teradata
当我在连接条件中使用真实 table 名称为 table 和质量别名时,为什么会出现 "Out of spool" 错误?
例如;
选择名称,ID 来自 emp_table E
内部联接
dep_tableD
在
emp_table.dep_no= D.dep_no
更新:解决来自评论follow-up的问题
当您使用 "real" table 名称进行限定时,Teradata 不会假设您指的是 table 的同一个实例作为您的别名。所以它是 cross-joining emp_table
的另一个实例(在您的示例中),它必须生成太多数据以供您的安装处理。 (即使它 运行 完成,它也会得到意想不到的结果,因为逻辑根本没有说出你的意思;见下文。)
如果您考虑一下,DBMS 将走上一条危险的道路,假设 emp_table.dep_no
与 E.dep_no
指的是同一个 table 实例;它将如何处理这个问题:
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
子句没有指定任何 table 作为 emp_table
来处理。 las,Teradata 通常允许隐式连接到新的 table 实例,只需引用它们即可。
所以我提到过,即使查询完成,您也会得到意想不到的结果。考虑一个小数据集的例子:
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
没关系,但现在您决定将员工排除在销售范围之外。但是您符合实际 table 名称而不是 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
返回了两行,它们与结果集的其余部分交叉连接(这就是为什么每个返回的记录都有重复项)。
当我在连接条件中使用真实 table 名称为 table 和质量别名时,为什么会出现 "Out of spool" 错误?
例如; 选择名称,ID 来自 emp_table E 内部联接 dep_tableD 在 emp_table.dep_no= D.dep_no
更新:解决来自评论follow-up的问题
当您使用 "real" table 名称进行限定时,Teradata 不会假设您指的是 table 的同一个实例作为您的别名。所以它是 cross-joining emp_table
的另一个实例(在您的示例中),它必须生成太多数据以供您的安装处理。 (即使它 运行 完成,它也会得到意想不到的结果,因为逻辑根本没有说出你的意思;见下文。)
如果您考虑一下,DBMS 将走上一条危险的道路,假设 emp_table.dep_no
与 E.dep_no
指的是同一个 table 实例;它将如何处理这个问题:
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
子句没有指定任何 table 作为 emp_table
来处理。 las,Teradata 通常允许隐式连接到新的 table 实例,只需引用它们即可。
所以我提到过,即使查询完成,您也会得到意想不到的结果。考虑一个小数据集的例子:
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
没关系,但现在您决定将员工排除在销售范围之外。但是您符合实际 table 名称而不是 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
返回了两行,它们与结果集的其余部分交叉连接(这就是为什么每个返回的记录都有重复项)。