私が歌川です

@utgwkk が書いている

sqlxで無理やり複数カラムに対するINクエリを書く

小ネタだしプロダクションで試したことはないです。ISUCONの練習をしていたらふと、これで複数カラムのINクエリが書けるのでは?? と思いついたのでメモ。

package main

import (
    "fmt"
    "log"
    "strings"

    "github.com/jmoiron/sqlx"
)

type WhereInArg struct {
    Name   string `db:"name"`
    Number int    `db:"number"`
}

func main() {
    whereInArgs := []WhereInArg{
        {
            Name:   "a",
            Number: 1,
        },
        {
            Name:   "b",
            Number: 2,
        },
    }
    query, args, err := sqlx.Named("SELECT * FROM tbl WHERE (`name`, `number`) VALUES(:name, :number))", whereInArgs)
    if err != nil {
        log.Fatal(err)
    }
    query = strings.Replace(query, "VALUES", "IN (", 1)
    fmt.Printf("%s (args: %#v)\n", query, args)
    // SELECT * FROM tbl WHERE (`name`, `number`) IN ((?, ?),(?, ?)) (args: []interface {}{"a", 1, "b", 2})
}

VALUES (:name, :number)VALUES (?, ?), (?, ?) に展開されるのがミソで、そこに括弧を足しつつうまく変換しているけど、プロダクションでやることはなさそう。placeholderを手で複製するか sqlx.In を使うことになる?