RAG・検索基盤

Text-to-SQLとは|集計の問いは、上位3件を数えると0/5だった

Text-to-SQLとは何をするのか文書検索で数えるのと何が違うのか生成された問い合わせ文をどう止めるのか

「合計金額はいくらか」という問いに、文書を上位3件取って数えても答えは出ません。40行のうち3行しか見ていないからです。

実際に測ったところ、表に問い合わせる方式は5問すべて正解、上位3件を数える方式は0/5でした。上位20件に広げても2/5です。

この記事の要点

  • 表への問い合わせは5/5、上位3件は0/5
  • 上位20件に広げても2/5
  • 全行を渡すと毎回1484字
  • 書き換えの文を止めないと、表から10行消える

集計の問いは、上位3件を数えると0/5だった

同じ40行を、表として問い合わせる場合と文書として検索する場合で測りました。集計の問いでは結果が分かれます。

Text-to-SQLが何を解いているのかを確かめるため、実際に走らせて測りました。用意したのは出張申請の表40行と、集計の問い5件です。

同じ40行を1行1文書の形にも変換して、文書検索で上位k件を取って数えるやり方と比べました。問い合わせはSQLiteで実際に実行しています。

javascript
const truth = db.prepare(t.sql).get().v;          // 表に聞く
for (const k of [3, 10, 20]) {
  const ids = bm25(t.q).slice(0, k).map((x) => x.i);   // 文書を上位k件取る
  got[k] = t.fromDocs(ids.map((i) => ROWS[i]));        // その範囲で数える
  if (got[k] !== truth) err[k]++;
}
text
問い                          表への問い合わせ  上位3件  上位10件  上位20件
申請の合計金額はいくらか                        722000    29100    116500    299000
開発課の申請は何件あるか                            10        3        10        10
金額が20000円を超える申請の件数                      16        0         3         4
海外出張の平均日数                             2.67        3      2.67      2.67
最も金額の大きい申請の金額                        28600    11400     19900     26700

答えが合っていた問いの数
  表への問い合わせ  5 / 5
  上位 3件を数える  0 / 5
  上位10件を数える  2 / 5
  上位20件を数える  2 / 5

上の表を見てください。合計金額の行では、正しい答えの722000に対して上位3件だと29100です。桁が違います。

一部を見て数えている

外れているのは検索が下手だからではありません。40行のうち3行しか渡していないからです。

上位20件に広げても合計は299000で、まだ届きません。全部を見ないと合計は出ないという当たり前のことが、そのまま結果に出ています。

全行を渡せばよいのか

全行を渡せば数えられます。ただし40行で1484字を毎回渡すことになります。上位3件なら108字です。

この計測は40行です。実際の業務の表は数万行から数百万行あります。渡すという選択肢は早い段階で消えます。

件数を増やしても、全部を見ないと合計は出ない。

単位: 円正しい答え722000円上位20件で数える299000円上位10件で数える116500円上位3件で数える29100円表40行での実測。上位k件を増やすほど近づくが、全行を見るまで一致しない。
図1 ── 合計金額の問いに対する答え
出典Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」2026-08-18 確認
10,181 questions and 5,693 unique complex SQL queries on 200 databases
原文Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」 この内容の有効期限2027-02-18

Text-to-SQLとは何をするのか

自然文の問いから、表に対する問い合わせ文を作らせます。答えは表が計算するので、集計が正確になります。

Text-to-SQLは、人が書いた問いから、表に対する問い合わせ文を作らせる手法です。

誰が計算するか

文書検索の構成では、渡された文書を読んで生成AIが数えます。前の節のとおり、渡した範囲でしか数えられません。

Text-to-SQLでは計算するのは表の側です。生成AIが作るのは問い合わせ文だけで、合計や件数は表が正確に出します。

通る段

  1. 表の構造を渡す。列の名前と型を伝える
  2. 問い合わせ文を作らせる。問いから機械が読める形に変える
  3. 実行する前に点検する。ここを飛ばすと危ない
  4. 実行して結果を渡す。数えるのは表の側

3番目を飛ばさないでください。生成された文をそのまま実行するのは、外から来た文をそのまま実行するのと同じです。点検の中身はこの記事の後半で扱います。

簡単な課題ではない

この課題は昔から研究されています。Spiderという評価用のデータは、200のデータベースに対する10,181件の問いと5,693件の一意で複雑なSQLから成ります。

そこで求められているのは、新しいSQLにも新しいスキーマにもよく一般化することです。手元の表に合わせて例文を用意しないと、思ったほど当たりません。

余談 使い分けの目安

文書検索とText-to-SQLは、どちらが優れているという関係ではありません。数える・足す・並べる問いは表に、文章の中身を読む問いは文書に向きます。前の節の計測でも、表への問い合わせが勝ったのは集計の問いだったからです。文書側の話はRAGの記事で扱っています。

出典Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」2026-08-18 確認
generalize well to both new SQL queries and new database schemas
原文Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」 この内容の有効期限2027-02-18

生成された問い合わせ文を実行する前に止める

点検を実際に動かしました。書き換えの文を通すと表が変わります。ただし形が正しくても中身が正しいとは限りません。

Text-to-SQL で生成された問い合わせ文をそのまま実行すると何が起きるのかを、実際に走らせて確かめました。5通りの文を用意しています。

点検は4つの規則だけです。複数の文が入っていないか、SELECTで始まるか、表にない名前がないか、件数の上限があるかを見ます。

text
文の種類        点検の結果                          点検を外して実行した場合
正しい集計           通した                                  4行返る・表は40行
存在しない列          止めた: 表にない名前が入っている(ryohi)             失敗(no such column: ryohi)
書き換え            止めた: SELECT で始まっていない                 0行返る・表は30行
複数の文            止めた: 複数の文が入っている                      1行返る・表は40行
上限のない全件         止めた: 件数の上限がない                        40行返る・表は40行

点検の前の表の行数: 40行

3行目を見てください。書き換えの文を実行すると、返る行は0件です。ところが表は40行から30行に減っています

何も返らないまま壊れる

0行返るという結果だけでは、異常に見えません。10行が消えたことは、返り値には出てこないからです。

だから実行に使う権限は読み取り専用にしておきます。点検の書き漏れがあっても、権限の側で止まります。二重にする理由がここにあります。

点検を通っても正しいとは限らない

1行目は点検を通り、4行が返りました。形としては問題のない文です

ただし、その4行が問いに対する答えとして正しいかどうかは点検では分かりません。点検が見ているのは形だけです。

Spiderの論文も、発表時点で最良のモデルでも完全一致の正解率は12.4%にとどまるとしています。近年の水準はこれより高くなっていますが、当たり外れがある前提で組む必要は変わりません。

形の点検と権限の制限は別のもの。両方置く。

充足 2 / 4SELECT 以外の文を止めている書き換えの文を通すと、0行返ったまま表が40行から30行に減る実行に使う権限が読み取り専用点検の書き漏れがあっても、権限の側で止まる点検を通れば答えも正しいと考えている点検が見ているのは形だけ。中身が問いに合っているかは別件数の上限を付けていない全件を返す文が通ると、表の行数だけ結果が返る表40行での実測にもとづく。点検は複数文・SELECT開始・列名・上限の4つの規則。
図2 ── 実行前に置く守りの点検項目
出典Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」2026-08-18 確認
the best model achieves only 12.4% exact matching accuracy
原文Yu et al.「Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task」 この内容の有効期限2027-02-18

よくある質問

上位k件を増やせば数えられますか
全行を取れば数えられますが、この計測では40行で1484字を毎回渡すことになります。行が増えるほど渡せなくなります。
生成された問い合わせ文は危なくないですか
書き換えの文が混ざると、実行した時点で表が変わります。この計測でも40行が30行になりました。
点検だけで足りますか
足りません。形が正しくても、問いに対する答えとして正しいかは点検では分かりません。
どんな問いに向きますか
数える・足す・並べる問いです。文章の中身を読む問いには、文書検索のほうが向きます。

まとめ

  • 自然文から問い合わせ文を作って表に聞く手法
  • 集計の問いは5/5と0/5で分かれた
  • 上位20件に広げても2/5
  • 実行前の点検と、読み取り専用の権限を両方置く

今日から始められること

  1. 自分の問いに、数える・足す問いが混ざっているか確かめる
  2. 混ざっていれば、その問いだけ表に聞く経路を用意する
  3. 問い合わせ文を実行する前の点検を書く
  4. 実行に使う権限を読み取り専用にする

実務で組んだText-to-SQLのワークフローには、値段が付きます

同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。

出品の仕組みを見る