生成AIにSQLを書いてもらうときの確認手順|そのまま実行しない5つのチェック

生成AIが書いたSQLを、実行前に列・条件・単位を読み、実行後に件数と合計を既知の数字と突き合わせて確かめる流れを表したイメージ AI活用
AIのSQLは、検算してから使う 補足: 実行前に3つ読み、実行後に2つ確かめる

生成AIに「9月の売上を出すSQLを書いて」と頼むと、それらしいSQLがすぐに返ってくる。実行するとエラーもなく数字が出る。でも、この数字をそのまま報告してよいのか分からない。

最初に確認したいのは、実行する前にSQLの「条件」を読み、実行した後に「件数と合計」をすでに分かっている数字と比べること です。SQLをゼロから書けなくても、確かめる場所が決まっていれば検算はできます。

この記事でわかること

  • AIに任せる作業と、人が確かめる作業の分け方
  • AIが書いたSQLをそのまま実行しない5つのチェック(実行前に読む3つ・実行後に数字で確かめる2つ)
  • 確認の手順を決めると業務の何が良くなるか(データ担当への依頼待ちが減り、誤った数字で報告しなくなる)

結論:AIに任せるのは「SQLを書く」まで。数字の定義と検算は人がやる

AIが書いたSQLは下書きです。実行してよいか、出た数字が正しいかを決めるのは、頼んだ人です。

生成AI(文章で頼むと、文章やSQLを作って返してくれるAI)は、SQLの下書きを書くのが得意です。一方で、会社の中で「売上」が何を指すか、どのデータを除くべきかは、渡された情報からしか分かりません。足りない部分を推測で埋めたまま、それらしいSQLを返すことがあります。

作業誰がやるか理由
SQLの下書きを書くAI書き方の候補をすぐに出せる
SQLの各行が何をしているかを説明するAI(説明は人が読んで確かめる)読めない箇所を減らせる
エラーメッセージの意味を調べるAI直す場所の見当がつく
「売上」「9月」など、数字の定義を決める人社内の定義はAIには分からない
実行してよいかを判断する人更新・削除のSQLはデータそのものを書き換える
結果を検算し、報告する数字を決める人数字に責任を持つのは頼んだ人

進め方は「頼む前に情報を渡す → 実行前に3つ読む → 実行後に2つ確かめる」の3段です。

頼む前に:テーブル定義と「数字の定義」を渡し、入力してよいかを先に確かめる

AIに渡す情報が少ないほど、AIは列の意味や条件を推測で埋めます。

SQLを頼むときは、次の6つを文章で渡します。

  • 目的:誰が、何の判断に使う数字か
  • DB製品名:PostgreSQL・MySQLなど(日付の書き方などの文法が製品ごとに違うため)
  • テーブル名・列名・型:特に日時の列が「日付だけ」か「日付と時刻」か
  • 1行の単位:注文1件で1行か、注文の中の商品1つで1行か
  • 数字の定義:「売上」は支払い済みだけか、キャンセルを除くか、税込か
  • 出してほしい形:どの列を、どの単位の行で出すか

あわせて、次の2つを頼みます。

  • 「SELECT文だけで書いてください」:データを読むだけのSQLに限り、更新・削除を含めないようにする
  • 「置いた前提を箇条書きで出してください」:期間の境界や除外した条件が書き出されるので、実行前に読む材料になる

入力する前に、テーブル定義やデータをAIに入れてよいかを、社内のルールと使うサービスの規約で確かめます。 会社によっては、使ってよいAIサービスや入力してよい情報の範囲が決まっています。テーブル名や列名も社内の情報です。SQLを書いてもらうだけなら、顧客名や金額などの実データは入れず、定義だけで頼めます。規約や社内ルールは変わることがあるため、使い始める前と、変更の案内があったときに確かめてください。

そのまま実行しない5つのチェック:実行前に3つ読み、実行後に2つ数字で確かめる

AIのSQLの確認は、全部を読み解くことではなく、数字がずれやすい5か所を順に見ることです。

#いつ確認することずれると起きること
1実行前テーブルと列が、渡した定義どおりか似た名前の別の列で集計し、定義と違う数字が出る
2実行前期間の境界・絞り込み・WHEREとONの位置月末のデータが漏れる、除くべきデータが混ざる
3実行前JOINとGROUP BYのあとの「1行の単位」行が増え、合計が膨らむ
4実行後各段階の件数どこで行が増えた・減ったかが分からない
5実行後すでに分かっている数字との突き合わせ誤った数字のまま報告する

その前提として、SELECT以外の文(UPDATE・DELETE・INSERTなど)が含まれていたら、実行しません。

1. テーブルと列:渡した定義にある列を、意図どおりの意味で使っているか

AIは、渡していない列名をもっともらしく補うことがあります。存在しない列ならエラーで止まるので気づけます。困るのは、実在する似た名前の列です。たとえば(架空の例ですが)税抜の「amount」と税込の「amount_with_tax」があると、どちらで集計しても、エラーなく数字が出ます。SQLに出てくる列を1つずつ、定義と見比べてください。

自分がAIに書いてもらったSQLでも間違いはあり、基本的には列名・テーブル名などの命名の間違いです。だいたい、実行したときか、自分でSQLを読んだときに気づきます。

2. 条件:期間の境界、絞り込み、WHEREとONの位置

条件は、次の3か所を読みます。

  • 期間:月初と月末の日が入っているか。日時の列に BETWEEN で日付だけを指定すると、月末日の0時より後が漏れます(具体例で確かめます)
  • 絞り込み:キャンセル・テストデータなど、除くべきものを除いているか。逆に、除きすぎていないか
  • LEFT JOINのとき:右側のテーブルの条件がWHEREにあると、残したかった行まで消えます

WHEREとONの違いは、次の記事で実行例つきで整理しています。

3. 単位:JOINとGROUP BYのあとで、1行が何を表すか

注文のテーブル(注文1件で1行)に明細のテーブル(注文の中の商品1つで1行)をJOINすると、1行の単位は明細になり、注文の金額が商品の数だけ繰り返されます。FROMとJOINのあとの1行、GROUP BYのあとの1行が何を表すかを、一言で言えるか確かめます。言えないときはAIに「このSQLの結果の1行は何を表しますか」と聞き、その答えも自分で確かめます。

粒度(1行が何を表すか)の確かめ方は、次の記事で詳しく書いています。

4. 件数:JOIN前後・集計前後で、件数がどう変わったか

実行したら、元のテーブルの件数、JOINしたあとの件数、集計したあとの件数を並べます。COUNT(*) は行の数、COUNT(DISTINCT order_id) は注文の数です。両方を出すと、JOINで行が増えたかどうかが分かります。

COUNTの使い分けと、ずれた場所を分解して探す方法は、次の記事で整理しています。

5. 突き合わせ:件数と合計を、すでに分かっている数字と比べる

比べる先は、次のどれかです。

  • 既存の月次レポートや、業務システムの管理画面に出ている数字
  • 前月に同じ条件で出した数字
  • JOINをせず、元のテーブルだけで件数と合計を出したSQLの結果

一致しないときは、日別・ID別に分けて、差の出ている行を探します。一致しない理由を説明できるまで、その数字は報告に使いません。

具体例:架空の注文データで、AIが書いたSQLを検算する

エラーなく動いても、期間の終わりの書き方1つで、9月の売上は3,000円ではなく1,000円になります(架空の例)。

以下は説明のための架空の例です。DBはPostgreSQLまたはMySQLを想定しています。ordered_at は日付と時刻を持つ列(日時型)です。

入力データ(orders)

order_idordered_atstatusamount
1012026-09-01 10:00paid1,000
1022026-09-30 15:00paid2,000
1032026-09-15 09:00canceled500
1042026-10-01 00:00paid3,000

「9月の支払い済み注文の件数と売上合計を出すSQL」を頼み、仮にAIが次のSQLを返したとします。

SELECT COUNT(*) AS order_count, SUM(amount) AS sales
FROM orders
WHERE status = 'paid'
  AND ordered_at BETWEEN '2026-09-01' AND '2026-09-30';

実行結果

order_countsales
11,000

なぜこうなるか:日時の列と ‘2026-09-30′ を比べると、’2026-09-30 00:00:00’ として扱われます。BETWEEN は「以上・以下」なので、範囲は9月30日の0時ちょうどまでです。9月30日15時の注文102が漏れます。ordered_at が日付だけの列(DATE型)なら、この書き方でも9月30日の注文は入ります。

どこで気づけるか:実行前ならチェック2で、期間の終わりが日付だけで書かれていることに気づけます。実行後ならチェック5で、管理画面などの「9月の支払い済み2件」と合わないことで気づけます。漏れた行は、月末日だけを取り出すと見つかります。

SELECT order_id, ordered_at, amount
FROM orders
WHERE status = 'paid'
  AND ordered_at >= '2026-09-30'
  AND ordered_at <  '2026-10-01';

この結果に注文102が出てくれば、元のSQLで漏れていた行だと分かります。

どう直すか:期間を「9月1日以上、10月1日より前」と書きます。

SELECT COUNT(*) AS order_count, SUM(amount) AS sales
FROM orders
WHERE status = 'paid'
  AND ordered_at >= '2026-09-01'
  AND ordered_at <  '2026-10-01';
order_countsales
23,000

「翌月1日より前」と書くと、時刻を持つ列でも日付だけの列でも同じ結果になり、10月1日0時の注文104も入りません。なお、日付を文字列で書く方法は、DB製品や設定によって扱いが変わります。頼むときにDB製品名を伝え、そのDBの書き方で書いてもらいます。

現場目線の注意点:「エラーなく動いた」は「数字が合っている」の証拠にならない

条件や単位のずれはエラーにならず、それらしい数字として出てきます。

エラーなく動いたことを、合っている根拠にしない。 具体例のSQLもエラーは出ず、1件・1,000円を返します。この数字が会議資料に載ると、あとから差し替えと説明が必要になり、同じ資料のほかの数字まで確かめ直すことになります。

AIが書いたSQLを、読めないまま保存して使い回さない。 翌月に別の人が使うとき、どの条件が何のためにあるかが分からず、作った人に聞くしかなくなります。SQLの先頭に -- で始まるコメント行を置き、目的・数字の定義・何と突き合わせて確かめたかを書いておきます。-- (ハイフン2つのあとに半角スペース)から行の終わりまではコメントとして扱われ、実行されません。個人的には、インデント(行頭の字下げ)をとことん綺麗にそろえるのが好きです。そろっていると、どの条件がどこにかかっているかを読み取りやすくなります。

業務への着地:依頼待ちが減り、誤った数字で報告しなくなる

確認の手順が決まっていれば、AIは依頼待ちを減らす道具になり、検算は誤った数字の報告を止める仕組みになります。

  • 依頼待ちが減る:数字を見たいたびにデータ担当に頼んで待っていた集計を、AIの下書きと5つのチェックで、自分で出せる範囲が広がります
  • 誤った数字で報告しない:件数と合計の突き合わせを報告前の決まりにすると、ずれが資料に載る前に止まります
  • 確認の仕方が人によって変わらない:5つのチェックをチームで共有すると、データ担当に見てもらうときも「何と突き合わせたか」から話せます

自分で出せる範囲を広げるのは、閲覧してよいデータ・使ってよいAIサービスなど、社内で許されている範囲の中で、が前提です。

まとめ

生成AIに書いてもらったSQLは、次の5つを確かめてから使います。

  1. テーブルと列が、渡した定義どおりの意味で使われているか
  2. 期間の境界・絞り込み・WHEREとONの位置が、意図どおりか
  3. JOINとGROUP BYのあとで、1行が何を表すかを言えるか
  4. 元のテーブル・JOIN後・集計後の件数がどう変わったか
  5. 件数と合計が、すでに分かっている数字と一致するか

頼む前には、テーブル定義と数字の定義を渡し、入力してよいかを社内のルールと規約で確かめます。書くのはAI、定義と検算は人、と分けておくと、AIのSQLを安心して業務に使えるようになります。

次に読む記事

タイトルとURLをコピーしました