結合操作を含むステートメントに関する SQL 規則
通常、 Db2 は、 SELECT ステートメントの他の節を評価する前に、最初にバインド操作を実行します。
SQL の規則では、SELECT ステートメントの結果は、
その文節が以下の順序で評価されたかのようになります。
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
結合操作は FROM 文節の一部です。したがって、 結合操作を含む SELECT ステートメントからどの行が戻されるかを予測するには、 結合操作が最初に実行されるということを念頭に置いてください。
例: パーツ名、供給業者名、製品番号、製品名についての
リストを PARTS 表と PRODUCTS 表から得るものとします。 PROD# 値が一方の表の PROD# 値
と一致していない、いずれかの表から行を組み込みたいものとします。つまり全外部結合を
必要としています。 さらに、製品番号 10 の行は除外するものとします。 次の SELECT ステートメントをよく考えてください。
SELECT PART, SUPPLIER,
VALUE(PARTS.PROD#,PRODUCTS.PROD#) AS PRODNUM, PRODUCT
FROM PARTS FULL OUTER JOIN PRODUCTS
ON PARTS.PROD# = PRODUCTS.PROD#
WHERE PARTS.PROD# <> '10' AND PRODUCTS.PROD# <> '10';次の結果は、期待した結果とは違います。PART SUPPLIER PRODNUM PRODUCT
======= ============ ======= ===========
PLASTIC PLASTIK_CORP 30 RELAY
BLADES ACE_STEEL 205 SAWDb2 は最初にバインド操作を実行します。 この結合操作の結果には、一方の表からの行 (その行は他方の表に 対応行がない) が組み込まれます。 しかし、次に WHERE 文節により、PROD# 列 の値が NULL の両方の表からの行が除外されます。
次のステートメントは、リストを作成する正しい SELECT ステートメントです。
SELECT PART, SUPPLIER,
VALUE(X.PROD#, Y.PROD#) AS PRODNUM, PRODUCT
FROM
(SELECT PART, SUPPLIER, PROD# FROM PARTS WHERE PROD# <> '10') X
FULL OUTER JOIN
(SELECT PROD#, PRODUCT FROM PRODUCTS WHERE PROD# <> '10') Y
ON X.PROD# = Y.PROD#;このステートメントでは、 Db2 はWHERE句を各テーブルに個別に適用します。 Db2 次に、一方のテーブルに該当する行がない行も含む、完全な外部結合操作を実行します。 最終結果では、PROD# 列の値が NULL の行が組み込まれ、 次のような出力になります。
PART SUPPLIER PRODNUM PRODUCT
======= ============ ======= ===========
OIL WESTERN_CHEM 160 -----------
BLADES ACE_STEEL 205 SAW
PLASTIC PLASTIK_CORP 30 RELAY
------- ------------ 505 SCREWDRIVER