2

Business Objects によって生成され、「昔ながらの」暗黙的な結合構文を使用するクエリを書き直しています。このコードは、1 つの部分でテーブルをそれ自体に結合し、「グローバル」where 句も備えています。例えば:

select   a.col1
       , b.col2
from     MYDB.TABLE a, MYDB.TABLE b
where    a.something=b.something_else
     and MYDB.TABLE.source='A'

上記は、質問の構成図です。実際のクエリは非常に長く、約 10 個のテーブルを結合しています。

私の質問: 上記のように、「余分な」場所条件は同じテーブルの両方のインスタンスに適用されますか? はいと思いますが、このようなコードはこれまで見たことがありません。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 句で 2 回参照されていることに注意してください。1 回はエイリアスを使用し、もう 1 回はエイリアスを使用していません。はい、このクエリは書かれたとおりに機能しますが、明示的な結合構文を使用するように書き直したいと思います(誰かがコメントしたように)。

クエリで EXPLAIN を実行したところ、「追加の」条件 (「Active」と「AGREEMENT」の場合) が実際にはテーブルの両方のインスタンスに個別に適用されているようです。

4

3 に答える 3

4

「余分な」条件は同じテーブルの両方のインスタンスに適用されますか?

いいえ、そうではありません。テーブルの 1 つのインスタンスにのみ適用されます。

さらに、そのように記述されたクエリは正しくありません。ほとんどの 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'
于 2012-10-18T15:36:34.760 に答える
3

あなたTRANSACTION MODEがオプティマイザーである場合、INNER JOIN の結果を含むスプール ファイルに対して、句TERADATA内の完全修飾テーブル参照を製品結合します。に設定してWHERE、これをまだテストできていません。TRANSACTION MODEANSI

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フィルタ条件が句のテーブルに適用されませんでした。

于 2012-10-18T16:27:11.673 に答える
2

クエリを解決する際にdbmsが最初に行うことの1つは、すべてのテーブルコンストラクター(FROM句、JOINなど)から作業テーブルを作成することです。

その直後に dbmsはWHERE句に移動し(動作するように動作し)、TRUEとしてテストされないすべての行を作業テーブルから削除します。

したがって、有効なWHERE句は、作業テーブルのすべての行に適用されます。初期のSQL標準委員会のメンバーであるひどいジョーセルコは、しばしばオンラインで処理する順序について書いています。(そのリンクのスレッドで「効果的に具体化する」を検索してください。)

于 2012-10-18T15:44:54.317 に答える