SQL に不慣れなユーザーでもデータ分析を行えるように、PolarDB for AI は、自然言語を SQL に変換する独自の AI モデルを提供します。この大規模言語モデル (LLM) ベースの自然言語から SQL への変換 (LLM ベースの NL2SQL) 機能は、組み込みモデルとして利用できます。この機能は、大規模言語モデル (LLM) を使用して、自然言語での質問を正確な SQL 文に直接変換します。これにより、コードを記述することなくデータベースと対話でき、データ分析と開発の効率が大幅に向上します。
この機能はカナリアリリース段階です。この機能をご利用になりたい場合は、チケットを送信して有効化を申請してください。
機能概要
PolarDB for AI は、インテリジェントな翻訳機として機能する NL2SQL 機能を提供します。これは、「上海で最も収益の高い店舗はどれか?」といった自然言語の質問を受け取り、それをデータベースのテーブルスキーマと組み合わせます。その後、LLM がこの入力を分析・理解し、データベースで直接実行可能な SQL 文を生成します。
コアワークフローには、以下のステップが含まれます:
テーブルスキーマインデックスの構築:データベースのテーブルスキーマ、カラム情報、コメント、サンプルデータをベクトル化して「データベースマップ」を作成します。このマップは、LLM がデータを理解するのに役立ちます。
NL2SQL 変換の実行:質問をすると、システムはその質問と「データベースマップ」を LLM に送信します。その後、モデルが対応する SQL 文を生成します。
(オプション) モデルのファインチューニング:汎用モデルが理解できない業界固有の用語 (「顧客トラフィック」など) や特定のクエリパターンに対して、モデルをファインチューニングできます。テンプレートやプロンプトを設定して、継続的に精度を向上させることができます。
注意事項
質問の方法:質問では、条件と関連するエンティティの値を明確に記述してください。条件を最初に置き、次に取得したいカラム値に対応するエンティティを続け、最後に考えられるカラム名を指定するようにしてください。例:
SELECT '部屋数が1つより多い「家」または「アパート」の物件名は何か?'この例では、「部屋数が1つより多い」が条件、「家」と「アパート」がカラム値に対応するエンティティ、「物件名」が考えられるカラム名です。
クエリ結果の精度:LLM ベースの NL2SQL は LLM に基づく AI モデルであり、そのパフォーマンスは多くの要因に影響されます。クエリ結果が期待どおりであることを確認するために、全体の精度に影響を与える可能性のある以下の要因を考慮してください:
テーブルとカラムのコメントの豊富さ:各テーブルとそのカラムにコメントを追加すると、クエリの精度が向上します。
質問とカラムコメントの一致度:質問内のキーワードのセマンティックな意味がカラムコメントに近いほど、クエリ結果は良くなります。
生成される SQL 文の長さ:SQL 文に含まれるカラムが少なく、条件が単純な場合、クエリはより正確になります。
SQL 文の論理的な複雑さ:SQL 文が使用する高度な構文が少ないほど、クエリはより正確になります。
操作手順
データテーブルの標準化
NL2SQL が機能するためには、モデルがテーブルの意味 (カラム名が何を表すかなど) を理解する必要があります。したがって、LLM ベースの NL2SQL を使用する前に、頻繁に使用するデータテーブルとそのカラムにコメントを追加してください。
テーブルコメント
LLM ベースの NL2SQL モデルがテーブルの基本情報をよりよく理解するのに役立ちます。これにより、モデルは SQL 文に関与するテーブルを特定しやすくなります。コメントは簡潔にし、注文や在庫など、テーブルの主要な内容を要約するようにしてください。コメントは 10 ワード未満に保ち、過度な説明は避けてください。
カラムコメント
カラムコメントは通常、注文番号、日付、店舗名などの一般的な名詞やフレーズで構成されます。これらのコメントは、カラム名の意味を正確に反映します。カラムコメントにサンプルデータや値のマッピングを追加することもできます。たとえば、
isValidという名前のカラムの場合、コメントは有効かどうか。0: いいえ。1: はい。のようにすることができます。
元のコメントを変更できない場合は、カスタムのテーブルおよびカラムコメント機能を使用して調整できます。詳細については、このドキュメントの関連セクションをご参照ください。
データ準備
このチュートリアルでは、架空の「アリシャンレストラン」管理システムを例として使用します。NL2SQL 機能の使用方法と、特定のビジネスシナリオに合わせてクエリ精度を最適化するためのモデルのファインチューニング方法をステップバイステップで説明します。
サンプルデータの準備 次の SQL 文を実行して、「アリシャンレストラン」システムの 3 つのコアテーブル (店舗テーブル、メニューテーブル、請求書テーブル) を作成します。
AI ノードのデータベースアカウントにビジネステーブルの権限を付与します。
たとえば、AI ノードに設定したデータベース接続アカウントが
polarai_userの場合、restaurant_info、menu_info、およびbill_infoテーブルの権限をpolarai_userに付与します。説明ビジネス環境でこれを適用する場合、AI ノードに設定されたデータベースアカウントが関連するビジネステーブルに対する権限を持っていることを確認してください。
-- 権限の付与 GRANT ALL PRIVILEGES ON TABLE public."restaurant_info" TO polarai_user; GRANT ALL PRIVILEGES ON TABLE public."menu_info" TO polarai_user; GRANT ALL PRIVILEGES ON TABLE public."bill_info" TO polarai_user;
基本的なクエリ
テーブルスキーマインデックスの作成 次のコマンドを実行して、現在のデータベース内のすべてのテーブルに対して
schema_indexという名前のテーブルスキーマインデックスを作成します。この操作は、テーブル構造、コメント、その他の情報を収集してベクトル化し、LLM にコンテキストを提供します。SELECT polar_ai.ai_BuildSchemaIndex('schema_index');このコマンドは、
bce632ea-97e9-11ee-bdd2-492f4dfe0918のようなタスク ID を返します。次のコマンドを使用してタスクのステータスを照会できます。ステータスがfinishになると、インデックス構築は完了です。SELECT polar_ai.ai_ShowTask('<your_task_id>');NL2SQL クエリの実行 これで、
ai_nl2sql関数を使用して、自然言語の質問を SQL に変換できます。単純なクエリ
質問:「今週の総収益はいくらですか?」
実行:
SELECT polar_ai.ai_nl2sql('今週の総収益はいくらですか?', 'schema_index');期待される SQL:
SELECT SUM(actual_amount) AS total_income FROM bill_info WHERE pay_time BETWEEN '2025-08-25' AND '2025-08-31';
より複雑なクエリシナリオ
NL2SQL は、ソート、結合、グループ化、計算を含む複雑な質問を処理できます。
ユーザーの質問
NL2SQL によって生成された SQL
各店舗の収益をソートしてください。
SELECT restaurant_id, SUM(actual_amount) AS total_income FROM bill_info GROUP BY restaurant_id ORDER BY total_income DESC;上海で最も収益の高い店舗はどれですか?
SELECT b.restaurant_id FROM restaurant_info r JOIN bill_info b ON r.id = b.restaurant_id WHERE r.position LIKE '%Shanghai%' GROUP BY r.position ORDER BY SUM(b.actual_amount) DESC LIMIT 1;上海の一人当たりの平均消費額はいくらですか?
SELECT AVG(bill_info.actual_amount / bill_info.diner_count) AS average_consumption_per_person FROM bill_info WHERE bill_info.restaurant_id IN (SELECT id FROM restaurant_info WHERE position = 'Shanghai');今月最も注文された料理のトップ 10 は何ですか?
SELECT mi.name, SUM(bi.items) as total_orders FROM bill_info bi JOIN menu_info mi ON bi.items = mi.id WHERE bi.pay_time >= '2024-10-01' AND bi.pay_time < '2024-11-01' GROUP BY mi.name ORDER BY total_orders DESC LIMIT 10;今月の収益の前月比成長率は何パーセントですか?
SELECT (SUM(CASE WHEN MONTH(pay_time) = 10 AND YEAR(pay_time) = 2024 THEN actual_amount ELSE 0 END) - SUM(CASE WHEN MONTH(pay_time) = 9 AND YEAR(pay_time) = 2024 THEN actual_amount ELSE 0 END)) / SUM(CASE WHEN MONTH(pay_time) = 9 AND YEAR(pay_time) = 2024 THEN actual_amount ELSE 0 END) * 100 AS growth_percentage FROM bill_info;上海で最も顧客トラフィックが多い店舗はどれですか?
SELECT r.position, COUNT(b.id) AS customer_flow FROM restaurant_info r JOIN bill_info b ON r.id = b.restaurant_id WHERE r.position LIKE '%Shanghai%' GROUP BY r.id ORDER BY customer_flow DESC LIMIT 1;これらの例から、NL2SQL がソート、結合、グループ化を含むほとんどの複雑なクエリを正確に処理できることがわかります。しかし、場合によっては、モデルの応答が論理的に正しいものの、期待を完全に満たしていないことに気づくかもしれません。
たとえば、「上海で最も収益の高い店舗はどれですか?」という質問に対して、モデルは店舗 ID (
restaurant_id) を返しますが、実際には店舗の住所や名前が欲しいかもしれません。これは、汎用 LLM がクエリのコアロジックは理解しているものの、結果フォーマットに対する暗黙的な期待を捉えきれていないために発生します。この問題は、質問を調整して「店舗名を返してください」と明示的に述べることで一時的に解決できます。しかし、体系的に精度を向上させ、ビジネス知識を組み込むためのより効果的な方法は、PolarDB for AI が提供するモデルのファインチューニング機能を使用することです。以下のセクションでは、モデルをファインチューニングしてこのような問題を解決する方法を示します。
高度な使用法:モデルのファインチューニングによる精度向上
PolarDB for AI は 4 つの高度なメソッドを提供します。以下の問題に遭遇した場合、対応するメソッドを使用して解決できます。
質問テンプレートの設定:一般的な質問テンプレートを設定して、モデルが特定の知識に基づいて SQL 文を生成できるようにします。
設定テーブルの構築:質問を前処理したり、生成された SQL 文を後処理したりします。
カスタムテーブルおよびカラムコメント:元のテーブルまたはカラムのコメントを変更できない場合、テーブルとそのカラムに新しいコメントを追加して、元のコメントをオーバーライドできます。
質問テンプレートの設定
質問テンプレートは特定の知識ドメイン向けに設計されており、モデルが質問をよりよく理解するのに役立ちます。一般的な質問テンプレートを設定し、特定の知識を導入してモデルをガイドできます。これにより、モデルはその知識に基づいて SQL 文を生成できます。
手順
質問テンプレートの設定
polar_ai拡張機能は、自動的に質問テンプレートテーブルを作成します。テーブルスキーマは次のとおりです:CREATE TABLE public.polar4ai_nl2sql_pattern ( id serial NOT NULL COMMENT 'プライマリキー' primary key, pattern_question text COMMENT 'テンプレートの質問', pattern_description text COMMENT 'テンプレートの説明', pattern_sql text COMMENT 'テンプレートの SQL', pattern_params text COMMENT 'テンプレートのパラメーター' ) ;質問テンプレートのカラムの説明
カラム名
説明
テンプレートの質問
LLM ベースの NL2SQL モデルへの入力として提供される、パラメーター付きの質問。
テンプレートの質問では、パラメーターは
#{XXX}の形式で記述する必要があります。テンプレートの説明
日付、年、組織などの一部のエンティティをパラメーターとして使用する、テンプレートの質問の洗練されたバージョン。これらのエンティティは通常、テーブル内の特定のカラムに対応します。
テンプレートの説明では、パラメーターは
[XXX]の形式で記述する必要があります。パラメーターの順序は、テンプレートの質問の順序と一致している必要があります。テンプレートの SQL
テンプレートの質問に対応する正しい SQL 文。この SQL 文では、テンプレートの質問からのパラメーターを変数として扱う必要があります。
説明テンプレートの質問とテンプレートの SQL のパラメーターは同じである必要はありませんが、関連している必要があります。たとえば、パラメーターは同じプレフィックスを持つ必要があり、それらの値の間には 1 対 1 のマッピングが存在する必要があります。
#{category}と#{categoryCode}を例にとると、categoryのパラメーター値が普通商標、特別商標、団体商標の場合、対応するcategoryCodeの値は 0、1、2 となります。詳細については、以下の例をご参照ください。テンプレートのパラメーター
table_name、param_info、explanationの 3 つのパラメーターで構成される JSON 文字列。パラメーターは次のように記述されます:table_name
string:テンプレート SQL 内のテーブル名。param_info
array:テンプレート SQL 内のパラメーターの説明。param_name
string:パラメーター名。value
array:パラメーターのサンプル値。説明パラメーターが有限の列挙値セットに対応する場合、value 配列にすべての可能な値をリストします。
値が単なる例である場合は、2〜4 つの値をリストできます。
相互に対応するパラメーターがある場合は、配列インデックスを使用してそれらをマッピングする必要があります。たとえば、
#{category}と#{categoryCode}の場合、categoryの「普通商標」はcategoryCodeの 1 に対応し、「特別商標」はcategoryCodeの 2 に対応します。詳細については、以下の例をご参照ください。
explanation
string:追加情報。これには通常、生成される SQL 文の要件 (どの情報を出力するか、特定のフィールドの説明など) が含まれます。
説明テンプレートパラメーターを記入する必要がない場合は、値を以下のいずれかに設定できます:
NULL
空の文字列
空のリスト文字列 []
例
テンプレートの質問
テンプレートの説明
テンプレートの SQL
テンプレートのパラメーター
コース名が #{courseName} で、指導状況が #{status} のコースをクエリする
[コース名] と [指導状況] のコースは何ですか?
SELECT course_name, course_time, course_location FROM courses WHERE course_name=#{courseName} AND status=#{statusCode}[{"table_name":"courses","param_info":[{"param_name":"#{courseName}","value":["数学","物理","化学","英語","歴史","地理","生物","コンピュータサイエンス","美術","音楽","体育","プログラミング","文学","心理学","哲学","経済学","社会学","物理実験","化学実験","生物実験"]},{"param_name": "#{status}", "value": ["未開始","進行中"]},{"param_name": "#{statusCode}","value": [0,1]}], "explanation": "コース名 (course_name)、コース時間 (course_time)、コース場所 (course_location) を出力します。注意:status は定数マッピングタイプです。変数マッピングフィールドは statusCode です。"}]
#{issueDate} 年にリリース予定で、プロジェクトステータスが #{projectStat} の国家標準をクエリする
[年] と [プロジェクトステータス] でリリース予定の国家標準は何ですか?
SELECT DISTINCT planNum, projectCnName, projectStat FROM sy_cd_me_buss_std_gjbzjh WHERE `planNum` IS NOT NULL AND `dataStatus` != 3 AND `isValid` = 1 AND projectStat=#{projectStat} AND DATE_FORMAT(`issueDate`, '%Y')=#{issueDate}[{"table_name":"sy_cd_me_buss_std_gjbzjh","param_info":[{"param_name":"#{issueDate}","value":[2009,2010,2011,2012]},{"param_name":"#{projectStat}","value":["意見募集中","公開済み","レビュー中"]}],"explanation":"標準名 (projectCnName)、計画番号、プロジェクトステータスを出力します。"}]
商標タイプが #{category} で、国際分類が #{intCls} の商標をクエリする
[商標タイプ] と [国際分類] の商標は何ですか?
SELECT DISTINCT tmName, regNo, status FROM sy_cd_me_buss_ip_tdmk_new WHERE dataStatus!=3 AND isValid = 1 AND category=#{categoryCode} AND intCls=#{intClsCode}[{"table_name":"sy_cd_me_buss_ip_tdmk_new","param_info":[{"param_name":"#{intCls}","value":["化学原料","顔料・塗料","日用化学品","燃料・油脂","医薬品"]},{"param_name":"#{category}","value":["普通商標","特別商標","団体商標"]},{"param_name":"#{intClsCode}","value":[1,2,3,4,5]},{"param_name":"#{categoryCode}","value":[0,1,2]}],"explanation":"商標名 (tmName)、出願/登録番号 (regNo)、商標ステータス (status) を出力します。注意:category は定数マッピングタイプです。変数マッピングフィールドは categoryCode です。intCls は定数マッピングタイプです。変数マッピングフィールドは intClsCode です。"}]
このトピックのシナリオを例として使用し、
public.polar4ai_nl2sql_patternテーブルにテンプレートを挿入します。たとえば、「[場所]で最も収益の高い店舗はどれか」という質問が、店舗の場所を正確に返すようにしたいとします。INSERT INTO public.polar4ai_nl2sql_pattern (pattern_question, pattern_description, pattern_sql, pattern_params) VALUES ( '#{position}で最も収益の高い店舗はどれか', '[場所]で最も収益の高い店舗はどれか', 'SELECT r.position FROM bill_info b JOIN restaurant_info r ON b.restaurant_id = r.id WHERE r.position LIKE ''%#{position}%'' ORDER BY b.actual_amount DESC LIMIT 1;', '[{"table_name":"bill_info","param_info":[{"param_name":"#{position}","value":["上海"]}], "explanation": "消費場所"}]' );ここで、
#{position}は任意の場所と一致するスロットです。pattern_sqlは、生成されることを期待する標準 SQL です。質問テンプレートインデックステーブルの作成
データベースの命名規則に準拠したカスタムインデックステーブル名を指定できます。このトピックでは、例として
pattern_indexを使用します。質問テンプレートインデックステーブルを作成する SQL 文は次のとおりです:SELECT polar_ai.ai_BuildSchemaIndex('pattern_index', '{"mode": "async", "resource": "pattern"}');説明質問テンプレートインデックステーブルを作成する前に、質問テンプレートテーブルに少なくとも 1 つのレコードが存在することを確認してください。
パラメーター
パラメーター
必須
説明
mode
はい
データ書き込みモード。非同期モードを示す async に設定します。
resource
はい
リソースタイプ。質問テンプレート情報がベクトル化されることを示す pattern に設定します。
このコマンドは、
bce632ea-97e9-11ee-bdd2-492f4dfe0918のようなタスク ID を返します。次のコマンドを使用してタスクのステータスを照会できます。taskStatusがfinishになると、インデックス構築は完了です。SELECT polar_ai.ai_ShowTask('<your_task_id>');説明public.polar4ai_nl2sql_patternテーブルのデータが変更された場合、インデックステーブルpattern_indexを再構築する必要があります。オンラインで質問テンプレートを使用する
クエリを実行する際、
pattern_index_nameパラメーターを使用して、先ほど作成したテンプレートインデックスを指定します。SELECT polar_ai.ai_nl2sql('上海で最も収益の高い店舗はどれか', 'schema_index', '{"pattern_index_name":"pattern_index"}');パラメーター
schema_indexは、現在のデータベースの取得インデックステーブルの名前です。pattern_index_nameは、質問テンプレートインデックステーブルの名前です。options内に複数のパラメーターを設定して、関連する動作を設定できます:パラメーター名
パラメーターの説明
値の範囲
pattern_index_top
取得する最も類似した質問テンプレートの数。
有効値:[1,10]。
デフォルト値は 2 で、現在の質問に対して最も最適なテンプレートの上位 2 つのみが選択されることを意味します。
pattern_index_threshold
取得した質問テンプレートが類似しているかどうかを判断するために使用されるしきい値。
有効値:(0,1]。
デフォルト値は 0.85 で、ベクトル一致スコアが 0.85 を超える質問テンプレートのみが選択されることを意味します。
設定テーブルの構築
質問を前処理したり、最終的に生成された SQL を後処理したりしたい場合は、設定テーブルを使用できます。
シナリオ
シナリオ 1:質問内の確定的な単語 (名前、業界固有の用語、製品名など) を置き換える。
例えば、
Zhang Sanを含むすべての質問について、Zhang SanをZS001に置き換えます。この場合、What were Zhang San's sales last month?やWhat are Zhang San's total sales this year?のような質問は、LLM が呼び出される前にWhat were ZS001's sales last month?やWhat are ZS001's total sales this year?に前処理できます。シナリオ 2:特定の単語を含む質問に追加情報を加える。
たとえば、
総売上を含むすべての質問に、総売上の計算式総売上 = SUM(売上)を追加します。LLM が呼び出される前に、設定テーブルを使用してこの情報を追加でき、質問が対応する条件を満たしたときに補足されます。シナリオ 3:特定のテーブルまたはカラムの値をマッピングして置き換える。
たとえば、
student_coursesテーブルを含むすべての最終 SQL 文で、カラム値マッピングのフォールバック措置としてstatus = 'Leave'をstatus = 0に置き換えます。
構文
polar_ai 拡張機能は、自動的に設定テーブルを作成します。テーブルスキーマは次のとおりです:
CREATE TABLE polar_ai.polar4ai_nl2sql_llm_config (
id SERIAL NOT NULL COMMENT 'プライマリキー' Primary Key,
is_functional tinyint NOT NULL DEFAULT 't' COMMENT 'アクティブかどうか',
text_condition text COMMENT 'テキスト条件',
query_function text COMMENT 'クエリ処理',
formula_function text COMMENT '数式情報',
sql_condition text COMMENT 'SQL 条件',
sql_function text COMMENT 'SQL 処理'
) ;polar4ai_nl2sql_llm_config テーブルのデータが変更された場合、何もする必要はありません。変更はすぐに有効になります。
パラメーター
カラム名 | 説明 | 値の範囲 | 例 |
is_functional | この行の設定がアクティブかどうかを指定します。 設定テーブルが存在する場合、デフォルトですべての NL2SQL 操作で使用されます。使用したくないが削除したくない設定項目がある場合は、is_functional を 0 に設定して設定行を非アクティブ化できます。 |
|
|
text_condition | 前処理:質問に対してテキスト条件チェックを実行します。 条件が満たされた場合、query_function と formula_function カラムが処理に使用されます。それ以外の場合は使用されません。 |
| text_condition が 例:
|
query_function | 前処理:質問を処理します。 text_condition が満たされた場合に使用されます。 |
| query_function が 例:
|
formula_function | 前処理:特定のビジネスコンセプトに関連する計算式やその他の情報を質問に追加します。 text_condition が満たされた場合に使用されます。 | - | formula_function が |
sql_condition | 後処理:モデルによって生成された SQL に対して条件チェックを実行します。 条件が満たされた場合、sql_function が SQL の処理に使用されます。それ以外の場合は使用されません。 |
| sql_condition= 例:
|
sql_function | 後処理:SQL を処理します。ビジネスロジックで値のマッピングを強制するために使用できます。 sql_condition が満たされた場合に使用されます。 |
| sql_function= |
例
サンプルデータ
is_functional | テキスト条件 | クエリ関数 | 数式関数 | SQL 条件 | SQL 関数 |
1 |
|
| |||
1 |
| ||||
1 |
|
|
シナリオ例
シナリオ 1:ビジネス用語の説明
LLM は「顧客トラフィック」の意味を理解していないかもしれません。「顧客トラフィック」または「客足」が「食事客の数の合計」であることを通知できます。
INSERT INTO public.polar4ai_nl2sql_llm_config (id, is_functional, text_condition, query_function, formula_function, sql_condition, sql_function) VALUES (
1,
1,
'顧客トラフィック||客足', -- 質問内のキーワードに一致
'',
'顧客トラフィックまたは客足は、食事客の数の合計として計算されます', -- LLM に提供される説明
'',
''
);この設定後、インデックスを再構築する必要はありません。「上海で最も顧客トラフィックが多い店舗はどれか?」と再度質問すると、モデルは diner_count フィールド (食事客の数) に基づいて正しい SQL を生成できます。
結果
質問:「上海で最も顧客トラフィックが多い店舗はどれか?」
実行:
SELECT polar_ai.ai_nl2sql('上海で最も顧客トラフィックが多い店舗はどれか', 'schema_index', '{"pattern_index_name":"pattern_index"}');返される期待される SQL:
SELECT r.position, SUM(b.diner_count) AS total_customer_flow FROM restaurant_info r JOIN bill_info b ON r.id = b.restaurant_id WHERE r.position LIKE '%Shanghai%' GROUP BY r.id ORDER BY total_customer_flow DESC LIMIT 1;
同様に、今月の収益の前月比成長率は何パーセントですか? という質問に対して、「前月比」と「前年比」の計算式を public.polar4ai_nl2sql_llm_config 設定テーブルに入力して、生成される SQL の精度を向上させることもできます。練習として試してみてください。
シナリオ 2:SQL クエリメソッドのヒントを提供
デフォルトでは、モデルは地名に対して完全一致 (=) を使用する可能性があり、クエリが失敗する原因となることがあります。店舗の場所にはあいまい一致 (LIKE) を使用するようにヒントを与えることができます。
INSERT INTO public.polar4ai_nl2sql_llm_config (id, is_functional, text_condition, query_function, formula_function, sql_condition, sql_function) VALUES (
2,
1,
'', -- 空の text_condition はグローバルに適用されることを意味します
'',
'店舗の場所 ''position'' のマッチングにはあいまい検索が必要です',
'',
''
);この設定は、モデルが「店舗の場所」を含むクエリを処理する際に LIKE を優先的に使用するのに役立ちます。
空の text_condition は、設定がグローバルに適用されることを意味します。
結果
質問:「上海の一人当たりの平均消費額はいくらですか?」
実行:
SELECT polar_ai.ai_nl2sql('上海の一人当たりの平均消費額はいくらですか?', 'schema_index');戻り値として期待される SQL:
SELECT AVG(b.actual_amount / b.diner_count) FROM bill_info b JOIN restaurant_info r ON b.restaurant_id = r.id WHERE r.position LIKE '%Shanghai%';
同様に、今月の収益の前月比成長率は何パーセントですか? という質問に対して、「前月比」と「前年比」の計算式を public.polar4ai_nl2sql_llm_config 設定テーブルに入力して、生成される SQL の精度を向上させることもできます。練習として試してみてください。
テーブルカラムコメントのカスタマイズ
データテーブルの標準化プロセス中に、既存のデータテーブルまたはカラムのコメントを変更できないことがわかった場合、polar4ai_nl2sql_table_extra_info テーブルにテーブルとそのカラムの新しいコメントを追加できます。NL2SQL を使用すると、このテーブルのコメントが元のテーブルのコメントをオーバーライドします。
構文
polar_ai 拡張機能は、自動的に polar4ai_nl2sql_table_extra_info テーブルを作成します。テーブルスキーマは次のとおりです:
CREATE TABLE polar_ai.polar4ai_nl2sql_table_extra_info (
id SERIAL NOT NULL PRIMARY KEY COMMENT 'プライマリキー',
table_name text COMMENT 'テーブル名',
table_comment text COMMENT 'テーブルコメント',
column_name text COMMENT 'カラム名',
column_comment text COMMENT 'カラムコメント'
);polar4ai_nl2sql_table_extra_info テーブルのデータが変更された場合、polar4ai_nl2sql_table_extra_info テーブルの変更を有効にするために、テーブルスキーマインデックスを再度作成する必要があります。
例
カスタムカラムコメント用のテーブルを作成します。
menu_infoテーブルのtypeカラムのコメントを変更します。ここでは、typeカラムに追加のオプション説明を追加します:料理の種類 1-肉料理、2-野菜料理、3-デザート。INSERT INTO public.polar4ai_nl2sql_table_extra_info (table_name, table_comment, column_name, column_comment) VALUES ('menu_info','メニューテーブル','type','料理の種類 1-肉料理、2-野菜料理、3-デザート');テーブルスキーマインデックスの作成操作を再実行します。
SELECT polar_ai.ai_BuildSchemaIndex('schema_index_new');このコマンドは、
bce632ea-97e9-11ee-bdd2-492f4dfe0918のようなタスク ID を返します。次のコマンドを使用してタスクのステータスを照会できます。taskStatusがfinishになると、インデックス構築は完了です。SELECT polar_ai.ai_ShowTask('<your_task_id>');
結果
質問:「最も野菜料理を販売している店舗はどれですか?」
実行:
SELECT polar_ai.ai_nl2sql('最も野菜料理を販売している店舗はどれですか?', 'schema_index_new');返される期待される SQL:
SELECT r.position FROM bill_info b, menu_info m, restaurant_info r WHERE b.restaurant_id = r.id AND b.items::jsonb ? m.id::text AND m.type = 2 GROUP BY r.position ORDER BY COUNT(*) DESC LIMIT 1;
出力は、モデルが料理の種類を menu_info テーブルの type カラムの値 2 にマッピングしたことを示しています。
付録:関連関数
_ai_nl2sql_alter_token
モデルサービスへのアクセスに必要なノードトークンを設定します。これは、NL2SQL 機能を使用する前に必要な初期化ステップです。
構文
text _ai_nl2sql_alter_token(text token);パラメーター
パラメーター | 説明 | 例 |
token | モデルサービスにアクセスするためのキー。 |
|
例
SELECT polar_ai._ai_nl2sql_alter_token('sk-xxxxxx');ai_BuildSchemaIndex
データベーススキーマまたは質問テンプレートのベクトル化されたインデックスを作成します。このインデックスは、LLM がデータ構造を理解するのに役立ち、NL2SQL 機能のコアステップです。これは非同期タスクです。
構文
text ai_BuildSchemaIndex(text name, jsonb text2vecOption default '{"mode": "async", "resource": "schema"}');パラメーター
パラメーター | 説明 | 例 |
name | 作成するインデックスの名前。オブジェクトの命名規則に準拠する必要があります。 |
|
| (オプション) ベクトル化プロセスの詳細なオプションを設定するために使用される |
|
text2vecOption の説明
パラメーター | 必須 | 説明 |
| いいえ | データ書き込みモード。デフォルトは |
| いいえ | ベクトル化されるリソースタイプ。
|
| いいえ | ベクトル化するテーブル名のリストを指定します。複数のテーブル名はコンマ ( |
| いいえ | カラム値をサンプリングするかどうかを指定します。カラム数が少ないテーブル (15 未満など) では、サンプリングは生成される SQL の品質を向上させるのに役立ちますが、インデックス構築時間が増加します。
|
| いいえ | NL2SQL 操作から除外するカラムを指定します。デフォルトは空の文字列 |
| いいえ |
|
戻り値
タスクのステータスを照会するために使用できる、一意の非同期タスク ID (job_id) を返します。
例
-- スキーマのインデックスを作成
SELECT polar_ai.ai_BuildSchemaIndex('my_schema_index');
-- 指定された 2 つのテーブルのスキーマインデックスを作成
SELECT polar_ai.ai_BuildSchemaIndex('my_schema_index_2', '{"mode": "async", "resource": "schema", "tables_included": "my_table1, my_table2"}');ai_ShowTask
ai_BuildSchemaIndex などの関数によって作成された非同期タスクの実行ステータスを、タスク ID に基づいて照会します。
構文
text ai_ShowTask(text job_id);パラメーター
パラメーター | 説明 | 例 |
job_id |
|
|
戻り値
タスクのステータスを返します:
init:タスクは初期化中です。Working:タスクは進行中です。Finish:タスクは正常に完了しました。
例
SELECT polar_ai.ai_ShowTask('bce632ea-97e9-11ee-bdd2-492f4dfe0918');ai_nl2sql
自然言語テキストを実行可能な SQL 文に変換します。
構文
text ai_nl2sql(text nl, text basic_index_name, jsonb options default '{}');パラメーター
パラメーター | 説明 | 例 |
| 変換する自然言語の質問。 |
|
| 使用するスキーマインデックスの名前。事前に |
|
| (オプション) SQL 生成の高度なオプションを設定するために使用される |
|
options の説明
パラメーター | 必須 | 説明 |
| いいえ | 生成された SQL を最適化するかどうかを指定します。
|
| いいえ | 取得する最も関連性の高いテーブルの数。有効値は |
| いいえ | テーブル取得の関連性しきい値。有効値は |
| いいえ | 使用する質問テンプレートインデックスの名前を指定します。 |
| いいえ | ( |
| いいえ | ( |
戻り値
生成された実行可能な SQL 文字列。
例
SELECT polar_ai.ai_nl2sql('今週の総収益はいくらですか?', 'schema_index');
-- 結果
SELECT SUM(actual_amount) AS total_income FROM bill_info WHERE pay_time BETWEEN '2025-08-25' AND '2025-08-31';ai_nl2chart
SQL クエリを実行し、リクエストに基づいてクエリ結果をチャートに変換し、チャートのダウンロード URL を返します。
この機能は、以下のバージョンで利用可能です:
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.10.11.0 以降)。
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.19.38.0 以降)。
構文
text ai_nl2chart(text sql, text usr_query);パラメーター
パラメーター | 説明 | 例 |
| 実行する SQL クエリ文。 |
|
| ユーザーによるチャートの自然言語での説明。 |
|
戻り値
公開アクセス可能な画像 URL を返します。
例
SELECT polar_ai.ai_nl2chart(
$$SELECT r.id, SUM(b.actual_amount) AS total_income FROM restaurant_info r JOIN bill_info b ON r.id = b.restaurant_id GROUP BY r.id$$,
'店舗の収益を表示'
);
-- 結果
-- http://db4ai-aiengine-cn-hangzhou-dataset-pre.oss-cn-hangzhou.aliyuncs.com/pc-xxx/xxx.png?security-token=...ai_nl2summary
SQL クエリを実行し、リクエストに基づいてクエリ結果の自然言語での要約を提供します。
この機能は、以下のバージョンで利用可能です:
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.10.11.0 以降)。
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.19.38.0 以降)。
構文
text ai_nl2summary(sql text, usr_query text);パラメーター
パラメーター | 説明 | 例 |
| 実行する SQL クエリ文。 |
|
| ユーザーによる要約の自然言語でのリクエスト。 |
|
戻り値
2 つの部分を含むテキストを返します:
sql_result text:元の SQL クエリ結果。summary_result text:結果の自然言語での要約。
例
SELECT polar_ai.ai_nl2summary(
$$SELECT r.id, SUM(b.actual_amount) AS total_income FROM restaurant_info r JOIN bill_info b ON r.id = b.restaurant_id GROUP BY r.id$$,
'全店舗の収益を要約する'
);
-- 結果
("[{""total_income"": 68, ""id"": 11}, {""total_income"": 70, ""id"": 9}, {""total_income"": 90, ""id"": 15}, {""total_income"": 66, ""id"": 19}, {""total_income"": 82, ""id"": 3}, {""total_income"": 94, ""id"": 17}, {""total_income"": 76, ""id"": 5}, {""total_income"": 92, ""id"": 4}, {""total_income"": 122, ""id"": 10}, {""total_income"": 104, ""id"": 6}, {""total_income"": 58, ""id"": 14}, {""total_income"": 68, ""id"": 13}, {""total_income"": 132, ""id"": 2}, {""total_income"": 124, ""id"": 16}, {""total_income"": 88, ""id"": 7}, {""total_income"": 74, ""id"": 12}, {""total_income"": 92, ""id"": 20}, {""total_income"": 92, ""id"": 1}, {""total_income"": 112, ""id"": 18}, {""total_income"": 106, ""id"": 8}]",)