AIにSQLを書かせるときは、データベース製品とバージョン、テーブル定義、欲しい結果を先に伝え、まず読み取り専用のSELECTで確認します。結果が返ることだけでは正しさは分かりません。JOINで行が増えていないか、NULLや重複をどう扱うか、対象件数が想定どおりかを小さな条件で検証し、更新系SQLは影響範囲と戻し方を決めるまで実行しないでください。
目次
SQLを書く前に、DBMSと作業環境を固定する
SQLの文法や関数、型、日付の扱い、トランザクション機能はDBMSごとに異なります。PostgreSQL、MySQL、BigQuery、SQL Serverなどのどれを使うかに加え、分かる範囲でバージョン、実行環境、権限、対象データベースを伝えます。製品名が不明な場合は、AIにSQLを作らせる前に管理者や接続設定で確認します。
本番環境か検証環境か、閲覧だけか書き込み権限もあるかも確認します。AIへ渡すschemaやsampleには、秘密情報や個人データを含めないようにし、共有が許されている範囲だけを使います。SQLを出力する段階で、実データへ接続したり、実行したりしたと誤解させないよう、「これは未実行の候補」と明確に分けてください。
問いをSELECT結果の仕様に置き換える
「売上上位の顧客を出す」では、売上の定義、対象期間、通貨、税、キャンセル、顧客の単位が不明です。欲しい列、対象期間、除外条件、集計単位、並び順、上限件数、NULLの扱いを一覧にします。可能なら、数行の架空データから期待する出力も作ります。期待値が決められない条件は、SQLへ埋め込まず確認事項として残します。
依頼例:
「PostgreSQL 16。orders(order_id, customer_id, ordered_at, amount, status)を使う。2026年4月のstatus='paid'の注文を顧客ごとに集計し、customer_id、件数、amount合計を返す。ordered_atはtimestamp、期間は4月1日を含み5月1日を含まない。cancelledは除外する。最初はSELECTだけ。JOINはしない。重複order_idがないか確認するqueryと、期待するgroupの小さな架空例を付ける。未確定の前提があればSQLを確定せず列挙する。」
この依頼例の日時・条件は説明用の架空設定です。実際の業務定義を自動で決めるものではありません。PostgreSQL公式文書ではSELECTが読み取り結果を取得するコマンドとして説明されていますが、実行権限やデータ量などは環境ごとに別途確認が必要です。
Schema・キー・制約をAIへ渡す
テーブル名と列名だけでなく、型、主キー、外部キー、NULL可否、unique制約、関連の向きを提示します。例えばorders.customer_idがcustomers.idを参照するのか、顧客ごとに複数の住所があるのかでJOINの結果は変わります。AIに実在しない列やrelationを補わせないため、schemaから確認できない項目は「不明」と伝えます。
データそのものを渡す場合は、実値ではなく、形式を保った架空値や匿名化済みサンプルを優先します。数値の桁、NULL、重複、日付境界など、SQLの挙動を確かめるために必要な特徴だけを残します。匿名化したつもりでも組合せで再識別される場合があるため、組織のルールと利用サービスの条件を確認します。
AIへ「このschemaに存在しない列は使わない」「不足している列があれば質問する」と伝え、出力SQLの各列を実定義と照合します。DBMSの公式referenceにあるsyntaxと異なる場合は、生成結果を採用せず修正します。識別子の大文字小文字、予約語、schema名、timezoneなども環境によって差が出るため、単に文法が通るだけでは確認完了になりません。
SELECTで結果の形と件数を確かめる
まず必要な列だけを選び、期間や状態などの条件を追加します。いきなり広い期間・全行を読むのではなく、LIMIT等で小さな範囲を確認し、件数が想定外なら条件を再確認します。LIMITは確認する行数を制限しても、集計・並べ替えなどの計算負荷を必ず軽くするとは限りません。データ量や実行環境が分からない場合は、担当者に負荷上限を確認してください。
JOINを加える前後で行数を比較します。主キーが一意のテーブルと結合しているか、1対多の関係で意図的に行が増えるのか、複数一致を集計するのかを整理します。重複が増えた結果をそのままSUMすると二重計上になることがあります。NULLは「値がゼロ」や空文字と同じとは限らず、比較・集計・結合条件の挙動を確認します。
表は横にスクロールできます
| 確認 | 実行前に決めること | 結果の見方 |
|---|---|---|
| 対象件数 | 期間・status・除外条件 | 想定件数との差を調べる |
| JOIN | relationと期待する粒度 | 結合前後の行数を比較 |
| 集計 | 一行の単位、重複の定義 | 小さな手計算と照合 |
| NULL | 未設定値の意味 | 0や空文字と混ぜない |
| sort / limit | 並び順、同順位の扱い | 欠落と上限を確認 |
JOIN・集計・日付条件を段階的に追加する
複雑なSQLを一度に生成せず、まず基礎となる行を確認し、その後にJOIN、集計、順位付けを足します。各段階で返る列と件数を記録し、どこで想定と違ったか追えるようにします。集計ではGROUP BYの単位、重複排除の基準、対象期間の境界を明示します。日付の時刻帯やtimezoneが関わる場合、DBの保存形式と利用者の業務時刻を揃えます。
PostgreSQLにはEXPLAINで実行計画を確認する機能があります。これは計画を表示するもので、実行時間や本番影響を保証するものではありません。EXPLAIN ANALYZEのように実際に文を実行するオプションを含む場合は、対象文の副作用や負荷を理解せずに使わないでください。計画の読み方が分からない、テーブルが大きい、実行時間の上限が不明な場合は、DB管理者と相談します。
UPDATE・DELETEへ進む前のGate
読み取り結果が正しくても、更新SQLが安全だとは限りません。INSERT、UPDATE、DELETE、DDLを実行する前に、対象行をSELECTで確定し、WHERE条件の対象件数と実際の対象レコードを確認します。WHERE句が欠けた場合や条件が広すぎる場合にどうなるかも確認してください。AIに実行させず、候補SQLとしてレビューに回します。
更新が必要なら、バックアップ、ステージングでの試行、権限、トランザクション、ロールバック方針を担当者と決めます。PostgreSQLのトランザクションは複数の操作をまとめ、未確定の変更をROLLBACKで取り消せる仕組みを提供します。ただし、外部処理やDDLの挙動、運用手順は製品・設定・クライアントに依存し、トランザクションを使えば全ての失敗が戻るとは限りません。対象DBの公式資料と運用手順を確認します。
出力をレビューしてから記録する
AIの回答を受け取ったら、実行可能なSQL、説明、想定出力、未確認前提を分けて保存します。schema内の全識別子、join key、期間の開始・終了、status値を照合し、サンプルで期待値と一致するか確認します。行数が過大・過少、NULLが想定外、同じキーが複数回出る場合は、そのまま続けず、どの条件で起きたかを切り分けます。
確認記録には、DBMSとversion、schemaの確認元、SQLの版、実行環境、レビュー担当者、件数、結果、未解決点を残します。AIが生成したという理由で、SQLの作成者や承認者を曖昧にしません。実行後に結果を業務へ使う場合も、データの所有者が内容を確認します。
AIものさしの判断
AIでSQLを書くときは、自然文から文を作ることより、データの意味と期待結果を固定し、安全に確かめる順番を作ることが重要です。SELECTを小さく検証し、件数・JOIN・集計を段階的に増やせるなら、AIを下書きと確認質問の作成に使えます。schemaが不明、対象件数を説明できない、write queryの戻し方がない、計画や負荷を評価できない場合は、本番実行へ進まず、DB責任者に不足情報を確認してください。
エラーと不一致を先に切り分ける
syntax errorならDBMS・version・識別子表記を確認します。結果が0行なら、期間の境界、timezone、status値、NULL、空白を順に見ます。想定より多い場合はJOINの多重一致や条件漏れ、少ない場合はINNER JOINで落ちた行や不一致の型を確認します。集計が合わないときは、明細の数行を手で合計し、SQLの粒度が業務上の一件と一致しているかを調べます。
表は横にスクロールできます
| 症状 | 優先して見る箇所 | 実行を止める条件 |
|---|---|---|
| 0行 | 期間境界、status、型、NULL | 条件の意味が未確定 |
| 行数が増える | JOINの一対多、重複key | 重複の扱いが不明 |
| 合計が違う | GROUP BY粒度、二重計上 | 期待値を独立に作れない |
| 遅い | EXPLAIN計画、対象範囲 | 負荷上限や権限が不明 |
| 更新範囲が広い | WHEREと対象件数 | 戻し方・承認がない |
原因を一つずつ変えて再確認し、条件をまとめて変更しないようにします。変更前後のqueryと件数を残せば、後から差分を追いやすくなります。
引用・データ出典
公式情報を編集部が見た内容です。Hands-on未実施の記述は本文かここに分けています。
確認日:2026年10月8日
PostgreSQL Docs:SELEC(新しいタブで開く)T
