我正在重写由Business Objects生成的查询,并使用“老式”隐式连接语法。代码在一个部分中将表连接到自身,并且还具有“global”where子句。例如:
select a.col1
, b.col2
from MYDB.TABLE a, MYDB.TABLE b
where a.something=b.something_else
and MYDB.TABLE.source='A'
以上是该问题的简要说明。实际查询很长,加入了大约十个表。
我的问题:如上所述,条件的“额外”是否适用于同一个表的两个实例?我想是的,但我以前从未见过这样的代码。我正在使用Teradata,但我认为这是一个普遍的SQL问题。
更新:也许我尝试缩小问题范围并不准确。这是我想要修改的完整查询:
SELECT
abs_contrct_prof.contrct_nbr_txt,
gbs_org_LVL1.bus_pln_sgmnt_cd,
abs_gnrc_lst_of_val_LVL1.wirls_val_1_txt
FROM
EDWABSUSERVIEWS.abs_contrct abs_contrct_prof,
EDWABSUSERVIEWS.gbs_org gbs_org_LVL1,
EDWABSUSERVIEWS.abs_gnrc_lst_of_val abs_gnrc_lst_of_val_LVL1,
EDWABSUSERVIEWS.abs_contrct,
EDWABSUSERVIEWS.gbs_sls_actv_blng_org_rltd,
EDWABSUSERVIEWS.gbs_sls_actv_org_rltd
WHERE
( abs_contrct_prof.type_cd = 'PROFILE' )
AND ( EDWABSUSERVIEWS.abs_contrct.type_cd = 'AGREEMENT' )
AND ( abs_contrct_prof.prnt_contrct_id=EDWABSUSERVIEWS.abs_contrct.contrct_id )
AND ( abs_contrct_prof.org_id=EDWABSUSERVIEWS.gbs_sls_actv_org_rltd.org_id )
AND ( EDWABSUSERVIEWS.gbs_sls_actv_org_rltd.gbs_lvl_3_org_id=EDWABSUSERVIEWS.gbs_sls_actv_blng_org_rltd.gbs_lvl_3_org_id )
AND ( EDWABSUSERVIEWS.gbs_sls_actv_blng_org_rltd.gbs_lvl_1_org_id = gbs_org_LVL1.org_id )
AND ( gbs_org_LVL1.bus_pln_sgmnt_cd=abs_gnrc_lst_of_val_LVL1.nm_txt and abs_gnrc_lst_of_val_LVL1.actv_ind = 'Y' and abs_gnrc_lst_of_val_LVL1.type_cd ='ABS_MOBILITY_SEGMENT' )
AND
abs_contrct_prof.contrct_nbr_txt IN @variable('FAN')
AND ( EDWABSUSERVIEWS.abs_contrct.sts_cd = 'Active' )
AND ( EDWABSUSERVIEWS.abs_contrct.type_cd='AGREEMENT' )
注意表EDWABSUSERVIEWS.abs_contrct
在FROM子句中被引用两次,一次使用别名而一次没有。是的,这个查询的工作原理是写的,但我想重写它以使用explict join语法(如有人评论)。
我在查询上运行了一个EXPLAIN,看起来条件(“Active”和“AGREEMENT”)的“额外”实际上分别应用于表的两个实例。
答案 0 :(得分:4)
条件的“额外”是否适用于同一个表的两个实例?
不,它没有。它仅适用于表的一个实例。
另外,查询写得不正确,它应该(并且可能会)在大多数SQL实现中给出错误。您必须命名为a
或b
:
select a.col1
, b.col2
from MYDB.TABLE a, MYDB.TABLE b
where a.something=b.something_else
and a.source = 'A' --or:-- and b.source = 'A'
答案 1 :(得分:3)
如果您的TRANSACTION MODE
为TERADATA
,优化程序产品将在WHERE
子句中针对包含INNER JOIN结果的假脱机文件加入完全限定的表引用。由于TRANSACTION MODE
设置为ANSI
,我无法对此进行测试。
示例强>
CREATE VOLATILE TABLE Test1
(
Col1 SMALLINT NOT NULL,
col2 VARCHAR(10) NOT NULL
)
PRIMARY INDEX (Col1)
ON COMMIT PRESERVE ROWS;
CREATE VOLATILE TABLE Test2
(
Col1 SMALLINT NOT NULL,
col2 VARCHAR(10) NOT NULL
)
PRIMARY INDEX (Col1)
ON COMMIT PRESERVE ROWS;
SELECT A.Col1
, B.Col2
, Test1.Col1
FROM Test1 A
, Test2 B
WHERE A.Col1 = B.Col1
AND Test1.Col1 = 1;
解释 - Teradata模式
1) First, we do an all-AMPs JOIN step from USER.B by way of a RowHash
match scan with no residual conditions, which is joined to USER.A
by way of a RowHash match scan with no residual conditions.
USER.B and USER.A are joined using a merge join, with a join
condition of ("USER.A.Col1 = USER.B.Col1"). The result goes into
Spool 2 (one-amp), which is redistributed by the hash code of (9)
to all AMPs. The size of Spool 2 is estimated with low confidence
to be 1 row (15 bytes). The estimated time for this step is 0.02
seconds.
2) Next, we do a single-AMP JOIN step from Spool 2 (Last Use) by way
of an all-rows scan, which is joined to USER.Test1 by way of the
primary index "USER.Test1.Col1 = 1" with no residual conditions.
Spool 2 and USER.Test1 are joined using a product join, with a
join condition of ("(1=1)"). The result goes into Spool 1
(all_amps), which is built locally on that AMP. The size of Spool
1 is estimated with low confidence to be 1 row (22 bytes). The
estimated time for this step is 0.01 seconds.
3) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.03 seconds.
<强>更新强>
INSERT INTO Test1 VALUES (1,'C');
INSERT INTO Test1 VALUES (2,'D');
INSERT INTO Test2 VALUES (1, 'C1');
INSERT INTO Test2 Values (2, 'D2');
<强>结果
Col1 Col2 Test1.Col1
----++----++----------
1 C1 1
2 D2 1
过滤条件未应用于FROM
子句中的表。
答案 2 :(得分:2)
dbms在解析查询时所做的第一件事(就像它一样)是从所有表构造函数(FROM子句,JOIN等)构建工作表。
在 之后,dbms立即(就像它去的那样)到WHERE子句,并从工作表中删除所有未测试为TRUE的行。
因此有效 WHERE子句适用于工作表中的所有行。早期SQL标准委员会的成员,暴躁的乔·塞尔科(Joe Celko)经常在网上撰写有关order of processing的文章。 (在该链接中搜索有效实现的主题。)