👯

【MySQL】フロントエンドエンジニアがMySQLのWITH句の便利さを知った話

2024/01/23に公開

はじめに

こんにちは。kouです。

自分は普段の開発業務ではフロントエンド及びバックエンドのどちらもを触ることが多いのですが、元々はフロントエンドに興味関心があってフロントエンドを中心に学習をしていたこともあり、バックエンド技術に関しては相対的に見てまだまだ広い知見がありません。

そんな自分が、最近業務内でMySQLのWITH句を使用する機会があり、SQLの可読性向上の観点からとても有用なものだと感じたので、今回はその紹介をします。

WITH句とは

WITH句とは、SQL(主にサブクエリ)の実行結果に対して名前をつけて一時的な仮想テーブルを作成し、それをメインクエリ内から参照できるというものです。別名を「共通テーブル式(Common Table Expressions, CTE)」と呼びます。

言葉だけでは伝わりづらいので、以下にサンプルコードを用いてその有用性を説明します。

まずはこちらのSQLを見てください。

-- メインクエリ
SELECT *
FROM table1 t1
WHERE ... = ( -- サブクエリ②
    SELECT *
    FROM (    -- サブクエリ①
        SELECT *
        FROM table2 t2
        JOIN ...
        WHERE ...
    )
)
ORDER BY ...

構造が分かりやすくなるよう詳細な部分は省略していますが、上記のようなSQLは比較的よく見かけると思います。よくあるサブクエリを含んだSQLです。

サブクエリは、メインクエリの中にネストして現れるため、可読性の観点から言えば、あまり読みやすいものではありません。というのも、コードを読解する際は、一番内側のサブクエリから順に読み下していく必要があるためです。

これはちょうど、以下のような入れ子になった関数実行のように、中で何が行われているのかを一番内側がどこであるのかを突き止めた上で、そこから遡って読み解いていく流れに似ています(※以下は関数になっている時点である程度可読性が高い状態になっていますが)。

funcC(funcB(funcA()));

こういった入れ子の関数実行は、可読性の観点から言えば、以下のように逐一変数に格納して次の関数の引数とする方が読みやすくなることは理解しやすいかと思います。

a = funcA();
b = funcB(a);

funcC(b);

これと同様のことをSQLでできるというのがWITH句のいいところです。

WITH句を用いると、最初に記載したSQLを以下のように書くことができます。

-- WITH句
WITH
    alias1 AS ( -- サブクエリ①を alias1 という名前で定義
        SELECT *
        FROM table2 t2
        JOIN ...
        WHERE ...
    ),
    alias2 AS ( -- サブクエリ② を alias2 という名前で定義
        SELECT *
        FROM alias1
    )

-- メインクエリ
SELECT *
FROM table1 t1
WHERE ... = alias2
ORDER BY ...
WITH句を使う場合と使わない場合のコード比較

上記コードの再掲です。

WITH句未使用
-- メインクエリ
SELECT *
FROM table1 t1
WHERE ... = ( -- サブクエリ②
    SELECT *
    FROM (    -- サブクエリ①
        SELECT *
        FROM table2 t2
        JOIN ...
        WHERE ...
    )
)
ORDER BY ...


WITH句使用
WITH
    alias1 AS ( -- サブクエリ①を alias1 という名前で定義
        SELECT *
        FROM table2 t2
        JOIN ...
        WHERE ...
    ),
    alias2 AS ( -- サブクエリ② を alias2 という名前で定義
        SELECT *
        FROM alias1
    )

-- メインクエリ
SELECT *
FROM table1 t1
WHERE ... = alias2
ORDER BY ...

メインクエリの部分がスッキリとし、可読性が高くなっていることが分かるかと思います。🐰

余談:WITH句との出会い

今回、ビジネスサイドが見るKPI集計ツールのSQLを改修するタスクがあり、そのタスクに取り組む中でWITH句の存在を知りました。

改修する対象のSQLを、同僚のバックエンドに強いエンジニアと一緒に事前確認する機会があり、その際に上記で例に挙げたようなサブクエリの中にサブクエリがあるようなSQLを見て、その同僚エンジニアが「今回の改修を機に、WITH句を使って読みやすくしたいですね(意訳)」と言っていたことが、今回のトピックであるWITH句を知ったきっかけです。

自分の働いている会社NoSchoolでは、基本的に出社制を採っていますが、こういったバックエンドに詳しいメンバーが近くにいてすぐにこういった会話が生まれるのはとてもありがたいですね。

おわりに

今回は、MySQLのWITH句について紹介しました。

WITH句を知ってまだ日が浅いため、WITH句のメリット及びデメリットについて正確に理解できているわけではありませんが、SQLを書く際には知っておいて損のない知識かと思いました。

フロントエンドエンジニアでも可読性の高いSQLが書ける!

GitHubで編集を提案
マナリンク Tech Blog

Discussion