8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIが生成するSQLクエリで閉包テーブルを階層表示

Last updated at Posted at 2024-08-23

背景

閉包テーブルからパス文字列を得るの記事を読んだことがきっかけです。
この記事のようにやりたいことは浮かんでいますが、SQLクエリを作るために少し工夫が必要そうなことは多々あるかと思います。

そこで、LLMを利用してSQLクエリを生成することで、考える作業を効率化できないかと考えました。
本記事では、AIを使って閉包テーブルの階層構造を表示するSQLクエリの生成を試みます。

AI利用時のデータ漏洩には注意が必要です
AIの学習に利用されないプラットフォームを選択するか、漏れてはいけない内容は入力しないようにしましょう。

AIが生成したクエリには注意が必要です
どんなクエリが作成されるかわからないため、必ず実行前に確認をしましょう。

目的

この記事では、AIを用いてSQLクエリを生成することを目的としています。
具体的には、閉包テーブルで表された部署を階層構造で出力するSQLクエリをLLMに生成させることを試みます。

環境

  • クエリ生成: AzureのGPT-4o
  • データベース: PostgreSQL 15.7

閉包テーブルの構造

テーブルは以下のように定義しています。
閉包テーブルで部署の構造を表現しています。

departments

部署情報を格納するテーブル

Column Type Constraints
department_id SERIAL PK
name VARCHAR(20) NOT NULL

department_tree_paths

部署の階層構造を保存するテーブル

Column Type Constraints
ancestor_id INTEGER PK, FK departments(department_id)
descendant_id INTEGER PK, FK departments(department_id)
depth INTEGER NOT NULL

使ったデータ

上記のテーブルには次のデータを挿入しました。
これらは、閉包テーブルからパス文字列を得るの記事で記載されたものを利用しています。

departments

department_id name
1 本社
2 営業部
3 営業1課
4 営業2課
5 東京支社
6 開発部
7 開発1課
8 開発2課

department_tree_paths

ancestor_id descendant_id depth
1 1 0
1 2 1
1 3 2
1 4 2
1 5 1
1 6 2
1 7 3
1 8 3
2 2 0
2 3 1
2 4 1
3 3 0
4 4 0
5 5 0
5 6 1
5 7 2
5 8 2
6 6 0
6 7 1
6 8 1
7 7 0
8 8 0

プロンプト

GPT-4oに投げたシステムプロンプト、ユーザプロンプトを紹介します。

システムプロンプト

以下のシステムプロンプトを用いました。
どんなことをするのかの概要と簡単なルールを与えています。
念の為SELECT文のみ生成するようにお願いしています。

あなたはユーザの入力からPostgreSQLのクエリを生成するAIです
以下の手順に従って段階的に考え、クエリを生成しましょう

1. `## question`に書かれた入力内容を確認してください
2. `## DB`に書かれたデータベースのテーブルとカラム情報を参考にして、クエリを生成してください

## クエリの生成ルール

- SELECT文のみを生成し、カラム名には適切な名前を考え別名をつけてください
- 回答はSQLのクエリのみ出力してください

ユーザプロンプト

ユーザプロンプトは以下のようにしました。
作って欲しいクエリの詳細に加えて、DBの構造を与えています。
DBの構造部分はCREATE文を貼り付けているだけです。

今回は参考記事に倣い、部署を/で区切り、階層が高い順で表示してみようと思います。

## question

部署IDが8の部署を階層構造で/で区切って表示してください
その際階層が高い方から順に表示してください

## DB

```
CREATE TABLE departments (
    department_id SERIAL PRIMARY KEY,
    name VARCHAR(20) NOT NULL
);
CREATE TABLE department_tree_paths (
    ancestor_id INTEGER REFERENCES departments(department_id),
    descendant_id INTEGER REFERENCES departments(department_id),
    depth INTEGER NOT NULL,
    PRIMARY KEY (ancestor_id, descendant_id)
);
```

生成結果

こちらが生成されたSQLクエリです。

SELECT   
    STRING_AGG(d.name, '/' ORDER BY dtp.depth DESC) AS department_hierarchy  
FROM   
    department_tree_paths dtp  
JOIN   
    departments d ON dtp.ancestor_id = d.department_id  
WHERE   
    dtp.descendant_id = 8  
GROUP BY   
    dtp.descendant_id;

このSQLクエリを実行すると、以下のような出力になります。
階層が高い順に/で区切られて出力されています。

department_hierarchy
本社/東京支社/開発部/開発2課

終わりに

今回の記事では、AIを利用して閉包テーブルの階層構造を表示するSQLクエリの生成ができました。
どの程度複雑なことができるのかの検証は必要ですが、プロンプトの工夫次第で様々なクエリを生成できる可能性があります。
ただし、冒頭で述べた通り、どんなものが生成されるかはわからないので、AIの生成結果を使う際は必ず内容を確認した上で使うようにしましょう

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?