どもです。
SQLで嵌ったので覚書。
状況としてはこんな感じ。
SELECT
CASE
WHEN 条件
THEN テーブル1.列A
ELSE テーブル1.列B
END AS 列AorB
テーブル1.列C
テーブル2.列D
テーブル2.列E
FROM
テーブル1 INNER JOIN テーブル2 ON 列AorB = テーブル2.列F
FRONをSELECTで生成した仮想列にしたいわけです。
しかし、これだと「Unknown column '列AorB' in 'on clause'」というエラーを食らってしまいます。
SELECTで生成した仮想列は、FROMにまで及んでくれないのですね。
そういえば、FROMでもCASEって使えるようです。
#1
SELECT
省略
FROM
テーブル1 INNER JOIN テーブル2 ON
(CASE
WHEN 条件
THEN テーブル1.列A
ELSE テーブル1.列B
END
)
= テーブル2.列F
これで解決です。
しかし、これ以外にも色々と方法があるそうで。
モノによって速度にも差が出るので、ちょっち列挙してみます。
#2
SELECT
省略
FROM
テーブル1 INNER JOIN テーブル2 ON
( 条件 AND テーブル1.列A = テーブル2.列F )
OR
( 条件の逆 AND テーブル1.列B = テーブル2.列F )
CASEを使わずとも、同じ結果を示してくれるものがありました。
どちらかというと、こっちのが見易いですかね。
デメリットは、条件の逆を書く必要があること。条件がNullならNotNullとしなければなりません。
ちょっと面倒なほか、条件が長いとミスの原因になりそうで辛い。
速度は①とほぼ同じのようです。
#3
(
SELECT
省略
FROM
テーブル1 INNER JOIN テーブル2 ON テーブル1.列A = テーブル2.列F
WHERE
条件
)UNION(
SELECT
省略
FROM
テーブル1 INNER JOIN テーブル2 ON テーブル1.列B = テーブル2.列F
WHERE
条件の逆
)
複数のSQLをくっつけるUNIONを使う方法。
メリットは、FROMがスッキリすること。
曰く複雑なFROMが重くなる原因だそうなので、FROM次第ではこちらの方が速くなるそうです。
デメリットは、2回SQLを実行していること。
逆にFROMがそこまで複雑でなければ、2周する分、遅くなります。
今回は、なんだかんだで①が採用されたのですが、
SELECTとFROMやWHEREはそれぞれ独立していること、
FROMやWHEREでもCASEや、サブクエリと呼ばれるものが使用できることを忘れないようにしたいと思います。