技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

SquirrelでネストクエリをLEFT JOIN【Go】

SQLビルダーのライブラリSquirrelです。SQL文の命令を、SQLの構文のようにGo言語によって記述することができます。

GitHub - Masterminds/squirrel: Fluent SQL generation for golang

使用方法は下記公式の案内に記載されていますが、

squirrel - GoDoc

sourcegraph.com


SELECTした結果(ネストクエリ)をLEFT JOINする方法にたどり着くまで時間がかかったので、備忘のため残します。

 nq := sq.Select(
        "p.id part_id",
        "p.name part_name",
        "o.id option_id",
        "o.name option_name",
        "p.category_id category_id").
        From("parts as p").
        LeftJoin("options as o ON p.id = o.part_id").
        Where(sq.Eq{"p.status": 1}).
        Where(sq.Eq{"o.status": 1})

    q := sq.Select(
        "c.id category_id",
        "c.name category_name",
        "po.part_id",
        "po.part_name",
        "po.option_id",
        "po.option_name").
        From("categories AS c").
        JoinClause(nq.Prefix("LEFT JOIN (").Suffix(") po ON c.id = po.category_id")).    // JOINに関する自由な記述ができるJoinClauseを使ってネストクエリを指定し、PrefixとSuffixを使ってstringで挟む
        Where(sq.Eq{"c.status": 1})

    rows, err := q.RunWith(r.msql).QueryContext(ctx)
    if err != nil {
        ...
    }

    for rows.Next() {
        ...
    }

期待されるクエリは下記の通りです。

SELECT
    c.id category_id,
    c.name category_name,
    po.part_id,
    po.part_name,
    po.option_id,
    po.option_name
FROM
    categories AS c
    LEFT JOIN
        (
            SELECT
                p.id part_id,
                p.name part_name,
                o.id option_id,
                o.name option_name,
                p.category_id category_id
            FROM
                parts AS p
                LEFT JOIN
                    options AS o
                ON  p.id = o.part_id
            WHERE
                p.status = ?
            AND o.status = ?
        ) po
    ON  c.id = po.category_id
WHERE
    c.status = ?,
    [[]s(int=1) %!!(MISSING)s(int=1) %!!(MISSING)s(int=1)]