UNIONの結果は常に、最初のSELECTの選択値のデータ型を使って表現されます。これはつまり、SELECT A UNION SELECT B は必ずしも、SELECT B UNION SELECT A と同じ結果を戻すとは限らないということです。ただし、どちらのケースでも同じ結果が戻されるよう、明示的に出力データ型を変換する場合は別です。
次の複雑な UNION を使った問合わせについて考えてみましょう。
SELECT MIN(X8.i1) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1=X1.i1 AND X8.i1 IN (SELECT COUNT(*) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1=X1.i1 AND X8.i1 = ANY (SELECT COUNT(*) FROM t7 X7 WHERE X7.i1 = ANY (SELECT AVG(X1.i1) FROM t1 X1))) UNION SELECT AVG(X4.i1) FROM t4 X4 WHERE X4.i1 = ANY (SELECT (X8.i1) FROM t1 X1 RIGHT JOIN t8 X8 ON X8.i1=X1.i1 AND X8.i1 = IN (SELECT MAX(X8.i1) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1=X1.i1 AND (SELECT (X4.i1) FROM t6 X6 RIGHT JOIN t4 X4 ON X6.i1=i1))));
結果は以下のように報告されます。
Minimum(i1) ----------- -2 0
直感的には、UNIONの両側の問合わせの順序を入れ替えても、同じ結果を生成するはずだと思えるかもしれません。最初のSELECTの選択値のデータ型が異なる場合があるので、必ずしもそのようにはなりません。同じデータベースにおける次の問合わせがそのことを例示しています。
SELECT AVG(X4.i1) FROM t4 X4 WHERE X4.i1 = ANY (SELECT (X8.i1) FROM t1 X1 RIGHT JOIN t8 X8 ON X8.i1 = X1.i1 AND X8.i1 = ANY (SELECT MAX(X8.i1) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1 = X1.i1 AND (SELECT (X4.i1) FROM t6 X6 RIGHT JOIN t4 X4 ON X6.i1 = i ) ) ) UNION SELECT MIN(X8.i1) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1 = X1.i1 AND X8.i1 IN (SELECT COUNT(*) FROM t8 X8 LEFT JOIN t1 X1 ON X8.i1 = X1.i1 AND X8.i1 = ANY (SELECT COUNT(*) FROM t7 X7 WHERE X7.i1 = ANY (SELECT AVG(X1.i1) FROM t1 X1 ) );
結果は以下のように報告されます。
Average(i1) ----------- -2 1
実際の平均は< 0.5 です。UNIONの中のSELECTの順序を逆にすると違いが生じるのはなぜでしょうか?一見矛盾した結果が生じる理由が、次のテーブルに説明されています。
最初のSELECTが指定する関数 | 結果のデータ型 | 結果として戻される値 |
---|---|---|
AVG | REAL | 1 |
MIN | INTEGER | 0に切り捨てられる |