エッジケースの例をいくつか教えていただけますか?
はい、来週また別のラウンドを予定しています。共有したリポジトリにあるRubyスクリプトを試すことができます。
@simon 本当の価値は、少なくとも当面の将来においては、物事が一度でうまくいくことは決してないということを理解することにあると思います。しかし、何をしたいのかがわかっていれば、執念深いインターンに指示を出すように、それを目指して導くことができます。そのインターンは雑務をこなしてくれます。
そのため、SQLについては「select from where」を覚えている以上の知識はなく、最終的にどうしたいのかはわかっていたものの、横で会話をするだけで、自分の仕事から手を離すことなく、目的のクエリを作成させることができました。本当に、私が正しい方向に導くだけでよい、無料のパーソナルアシスタント/インターンのようです。
まず、最終的なクエリを以下に示します。最も多くの合計いいねを獲得した上位100ユーザーを返し、そのユーザー、ユーザー名、合計いいね数、そして最もいいねを獲得した単一の投稿へのリンクを提供するクエリを求めていました。これをどうやって取得するのか全くわからず、正直どこから手をつければよいのかもわかりませんでした。このようなものが欲しいときは、エンジニアの一人に頼んでいました。彼らに迷惑をかけず、自分の仕事のペースを落とすことなく、ChatGPTを指示・誘導して必要なことを完了させることができました。
最終クエリ:
WITH Most_Liked_Posts AS (
SELECT
p.user_id,
p.topic_id,
p.post_number,
ROW_NUMBER() OVER (PARTITION BY p.user_id ORDER BY likes_count DESC) AS row_number
FROM (
SELECT
p.user_id,
p.topic_id,
p.post_number,
COUNT(l.id) AS likes_count
FROM
posts p
LEFT JOIN post_actions l ON p.id = l.post_id AND l.post_action_type_id = 2
WHERE
p.user_id NOT IN (SELECT id FROM users WHERE username = 'codey')
GROUP BY
p.user_id,
p.topic_id,
p.post_number
) p
),
User_Likes AS (
SELECT
u.id AS user_id,
COUNT(pa.id) AS total_likes
FROM
users u
LEFT JOIN posts p ON u.id = p.user_id
LEFT JOIN post_actions pa ON p.id = pa.post_id AND pa.post_action_type_id = 2
WHERE
u.username != 'codey'
GROUP BY
u.id
)
SELECT
ul.user_id,
u.username AS username,
ul.total_likes,
'\u003ca href=\"/discuss/t/' || mlp.topic_id || '/' || mlp.post_number || '\"\u003e' || 'Link to most-liked post' || '\u003c/a\u003e' AS html$post
FROM
User_Likes ul
JOIN users u ON ul.user_id = u.id
LEFT JOIN Most_Liked_Posts mlp ON ul.user_id = mlp.user_id AND mlp.row_number = 1
ORDER BY
ul.total_likes DESC
LIMIT 100
プロンプト開始前のChatGPTアカウントでの指示:
PostgreSQLに関連する質問のみをします。関連するSQLクエリのみで回答してください。
これらのクエリはすべて、私のコミュニティプラットフォームであるDiscourseのデータベースに関連しています。
SQLクエリとクエリの説明で回答してください。SQLステートメントの末尾にセミコロンを使用しないでください。必要ありません。
ChatGPTでのこのクエリ作成の全会話はこちらで確認できます:
@sam 上記のような完全なスキーマ(申し訳ありませんが、これをどこで入手できるのか、またこの形式で入手する方法がわかりません)と、langchain およびベクトルデータベースを使用して、ドキュメントを ChatGPT に送信する 前に 正しく処理し、さらに Data Explorer の使用に関するドキュメントがあれば、このプロセスはほぼ魔法に近いものになると確信しています。
ベクトルDBを試して類似の例をフィードしましたが、それはあまりにも強く誘導しすぎます。魔法のような効果を得るには、おそらく1000個の非常に近い例が必要になるでしょう。
エンジニアにも試してもらいます。私たちはこれらをかなり迅速に生成するための「ファクトリー」のようなものを作りました。
この形式のすべてのデータベーススキーマの完全かつ網羅的なドキュメントを入手できる場所はありますか?
# == Schema Information
#
# Table name: application_requests
#
# id :integer not null, primary key
# date :date not null
# req_type :integer not null ("http_total"=>0,"http_2xx"=>1,"http_background"=>2,"http_3xx"=>3,"http_4xx"=>4,"http_5xx"=>5,"page_view_crawler"=>6,"page_view_logged_in"=>7,"page_view_anon"=>8,"page_view_logged_in_mobile"=>9,"page_view_anon_mobile"=>10,"api"=>11,"user_api"=>12)
# count :integer default(0), not null
#
# Table name: users
#
# id :integer not null, primary key
# username :string(60) not null
# created_at :datetime not null
# updated_at :datetime not null
# name :string (the user's real name)
# last_posted_at :datetime
# active :boolean default(FALSE), not null
# username_lower :string(60) not null
# last_seen_at :datetime
# admin :boolean default(FALSE), not null
# trust_level :integer not null
# approved :boolean default(FALSE), not null
# approved_by_id :integer
# approved_at :datetime
# previous_visit_at :datetime
# suspended_at :datetime
# suspended_till :datetime
# date_of_birth :date
# ip_address :inet
# moderator :boolean default(FALSE)
# title :string
# locale :string(10)
# primary_group_id :integer
# registration_ip_address :inet
# staged :boolean default(FALSE), not null
# first_seen_at :datetime
# silenced_till :datetime
その形式はトークン効率が非常に悪いですが、データエクスプローラーのpgスキーマテーブルからクエリで取得できます ![]()
ハハ、わかりました。彼に確認してもらいます。言ったように、私はこれ以上深く追求する人間ではありません。もしそうなら、こんな質問はしていないでしょう!
何かを機能させたいのですが、これは非常に難しい問題です
これは単なるアイデアであり、試したことはありません。
IMOで必要とされるクエリは、職務に基づいた使用法に分解できます。
- モデレーター
- 管理者
- 開発者
したがって、必要とされるテーブルは、徐々に大きくなるセットにグループ化でき、最小のセットはモデレーターに必要なテーブルです。
現在、モデレーターが必要とするデータの多くは、特定の列が必要なテーブルの共通結合に基づいています。したがって、ビューが必要です。
スキーマ全体ではなく共通ビューを使用する場合、多くのプロンプトでスキーマ全体ではなくビューを渡すだけで済むため、LLMが可能なソリューションを生成するのがはるかに簡単になる可能性があります。
お役に立てば幸いです。
はるかに難しいクエリについては、そのようなクエリが必要だと知っているなら、クエリを構築するのに十分な知識がある可能性が高いです。
それを試しました。結果はバラバラです。興味深い実験は、SQLの能力をテストするために、Discourseデータベーススキーマの最小限のアノテーション付きバージョンをGPT-3.5に提供することです。トークンの効率は悪いことは承知していますが、読みやすいです。
最小スキーマ
# == スキーマ情報
#
# テーブル名: users
#
# id :integer not null, primary key
# username :string(60) not null
# created_at :datetime not null
#
# テーブル名: groups
#
# id :integer not null, primary key
# name :string not null
# created_at :datetime not null
#
# テーブル名: group_users
#
# id :integer not null, primary key
# group_id :integer not null
# user_id :integer not null
#
# テーブル名: posts
#
# id :integer not null, primary key
# user_id :integer
# topic_id :integer not null
# deleted_at :datetime (アプリケーションは投稿を「ソフトデリート」します。投稿が削除されると、`deleted_at` プロパティが `:datetime` に設定されます。削除された投稿を返すように明示的に要求されない限り、投稿に関連するデータを要求するクエリを作成する際に、`deleted_at` 列が `NOT NULL` であることを確認してください。)
#
# テーブル名: topics
#
# id :integer not null, primary key
# title :string not null
# category_id :integer
# created_at :datetime not null
# user_id :integer (トピックを作成したユーザーのID)
# deleted_at :datetime (アプリケーションはトピックを「ソフトデリート」します。トピックが削除されると、`deleted_at` プロパティが `:datetime` に設定されます。削除されたトピックを返すように明示的に要求されない限り、トピックに関連するデータを要求するクエリを作成する際に、`deleted_at` 列が `NOT NULL` であることを確認してください。)
#
# テーブル名: categories
#
# id :integer not null, primary key
# name :string(50) not null
これまでのところ、得られている結果は印象的です。プロンプトにアノテーション付きスキーマを提供するだけで問題が解決する可能性があると考えています。
楽しみのために、GPT-3.5にどのようなクエリで苦労するか尋ねてみました。
GPT-3.5の制限
- 階層クエリ: 再帰的な関係のような階層的なデータ構造を含むクエリは複雑になる可能性があります。例えば、カテゴリ階層内の親-子関係をクエリすることなどです。
- 時間的クエリ: 履歴トレンドの計算や特定の時間間隔でのデータの分析など、時間ベースのデータを含むクエリは、より複雑なSQL構文が必要になる場合があります。
- ウィンドウ関数: 以前のクエリでウィンドウ関数を使用しましたが、複雑な分析タスクのためのウィンドウ関数のより高度な使用は困難な場合があります。
- 地理空間クエリ: 空間データベースや、近くの場所や複雑な空間関係の検索などの地理データに基づいたクエリは、複雑になる可能性があります。
- 複雑な集計: 複数のグループ化レベルと計算を含む高度な集計は、より複雑なSQL知識が必要になる場合があります。
- 最適化クエリ: インデックス、クエリチューニング、パフォーマンス改善を含む、高度に最適化されたクエリの作成は複雑になる可能性があります。
- カスタムアルゴリズム: クエリロジックの複雑さにより、SQLクエリ内にカスタムアルゴリズムまたはロジックを実装することは困難な場合があります。
- 高度なJOIN: 複雑なJOIN条件や複数のJOINの結合は、慎重な検討と、より複雑なSQL構文が必要になる場合があります。
- サブクエリと相関サブクエリ: サブクエリは処理できますが、非常に複雑または深くネストされたサブクエリはより困難になる可能性があります。
- ピボットとアンピボット: データの幅広形式と縦長形式間の変換(ピボットとアンピボット)は、特定のシナリオで複雑になる可能性があります。
問題が発生しているのは、データベーススキーマ全体を曖昧にすることです。例えば、user_actions テーブルにアノテーションを付ける方法を見つけることです。その action_type コードの定義を提供するだけでは不十分です。user_id、target_user_id、acting_user_id について推測し始めます。
最も一般的に要求されるクエリは、データベースのほとんどのテーブルや列を使用しません。データエクスプローラーにAIを追加する場合、「基本」モードと「高度」モードを検討する価値があるかもしれません。基本モードは、ほとんどのユースケースをカバーするプロンプトを提供できます。高度モードでは、ユーザーがプロンプトに設定する情報を選択できます。
GPT-3.5が正常にクエリを作成できるようにするために、メタに対するクエリの要求から逆算して、プロンプトに何を提供する必要があるかを確認するのは興味深いかもしれません。
まずgptにどのテーブルが関連しているかを判断させ、次にsqlを生成する第二段階に進むというlangchainのアプローチが役立つ可能性があります。
当社の製品では、現在LangChainを使用する独自のインプリメンテーションを採用しています。再利用可能なファクトリを構築しましたので、近いうちにリードエンジニアに試してもらう予定です。
しかし、前述したように、これまでの結果には非常に満足しています。まるで、私に代わって用事をこなしてくれるアシスタントがいるようなものです。まだ数回のやり取りが必要ですが、現時点でも時間とお金を大幅に節約できます。
FYI
This is super addictive. Based on the “LLMs and SQL” blog post, and a bit of trial and error, I created this prompt that contains a partial description of the Discourse database:
Discourse database prompt
The text between the /* Discourse database documentation start */ and /* Discourse database documentation end */ comments contains details about the Discourse forum application's PostgreSQL database.
All tables and columns are outlined in the `CREATE TABLE` statements. Take note of the sample queries that follow each of the `CREATE TABLE` statements. Some additional important details are contained in
inline (`-- --`) and multi-line (`/* */`) comments. After having sent you this information, I will ask you to write some queries that are to be run by the Discourse Data Explorer plugin. All of the tables and columns
required to write these queries are in the `CREATE TABLE` statements that I have sent you.
/* Discourse database documentation start */
CREATE TABLE users (
id integer NOT NULL, -- the application has the concept of 'real' users. A 'real' user is a user with an id > 0 --
username character varying(60) NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
name character varying,
seen_notification_id integer DEFAULT 0 NOT NULL,
last_posted_at timestamp without time zone,
password_hash character varying(64),
salt character varying(32),
active boolean DEFAULT false NOT NULL,
username_lower character varying(60) NOT NULL,
last_seen_at timestamp without time zone,
admin boolean DEFAULT false NOT NULL,
last_emailed_at timestamp without time zone,
trust_level integer NOT NULL,
approved boolean DEFAULT false NOT NULL,
approved_by_id integer,
approved_at timestamp without time zone,
previous_visit_at timestamp without time zone,
suspended_at timestamp without time zone,
suspended_till timestamp without time zone,
date_of_birth date,
views integer DEFAULT 0 NOT NULL,
flag_level integer DEFAULT 0 NOT NULL,
ip_address inet,
moderator boolean DEFAULT false,
title character varying,
uploaded_avatar_id integer,
locale character varying(10),
primary_group_id integer,
registration_ip_address inet,
staged boolean DEFAULT false NOT NULL,
first_seen_at timestamp without time zone,
silenced_till timestamp without time zone,
group_locked_trust_level integer,
manual_locked_trust_level integer,
secure_identifier character varying,
flair_group_id integer,
last_seen_reviewable_id integer
);
SELECT * FROM users WHERE id = 1 OR id = 2 OR id = 121;
id | username | created_at | updated_at | name | seen_notification_id | last_posted_at | password_hash | salt | active | username_lower | last_seen_at | admin | last_emailed_at | trust_level | approved | approved_by_id | approved_at | previous_visit_at | suspended_at | suspended_till | date_of_birth | views | flag_level | ip_address | moderator | title | uploaded_avatar_id | locale | primary_group_id | registration_ip_address | staged | first_seen_at | silenced_till | group_locked_trust_level | manual_locked_trust_level | secure_identifier | flair_group_id | last_seen_reviewable_id | password_algorithm
-----+----------+----------------------------+----------------------------+--------------+----------------------+----------------------------+------------------------------------------------------------------+----------------------------------+--------+----------------+----------------------------+-------+----------------------------+-------------+----------+----------------+----------------------------+----------------------------+----------------------------+-------------------------+---------------+-------+------------+------------+-----------+------------+--------------------+--------+------------------+-------------------------+--------+----------------------------+---------------+--------------------------+---------------------------+------------------------------------------+----------------+-------------------------+------------------------------
1 | scossar | 2019-04-26 22:59:44.685893 | 2023-08-14 04:40:20.823438 | Simon Cossar | 56395 | 2023-08-14 04:08:43.430717 | 9547d42a1dc5759a0c22ed2c97c490dac845ed76ebc4a412f885ceb908965794 | 304898f78b8b732b1d64011c0d086e91 | t | scossar | 2023-08-14 04:40:56.769353 | t | 2023-08-14 04:33:46.44485 | 3 | t | -1 | 2020-09-22 19:54:41.05418 | 2023-08-13 22:35:00.020816 | | | 1904-02-14 | 0 | 0 | ::1 | t | Member | 747 | | | | f | 2019-04-26 23:10:43.250255 | | | 3 | | | 432 | $pbkdf2-sha256$i=64000,l=32$
2 | sally | 2019-04-26 23:15:47.859691 | 2023-08-14 04:40:56.831344 | | 56396 | 2023-08-14 04:11:37.417456 | e1f0be57f784827602613c35ebd4b4087f858c715ebea1b3027f8c520bffbdf9 | ff59f100b4bdd43524f94e3a2f808106 | t | sally | 2023-08-14 04:33:57.054779 | f | 2023-08-14 04:33:06.727322 | 2 | t | -1 | 2020-05-19 19:35:15.79381 | 2023-08-13 22:08:05.099486 | | | | 0 | 0 | 127.0.0.1 | t | Regular | 22 | en | 49 | 127.0.0.1 | f | 2019-04-26 23:16:58.912958 | | | | a292161dd2ebbedbcd0e79f96baca06d9f399083 | 194 | 432 | $pbkdf2-sha256$i=64000,l=32$
121 | Ben | 2019-11-15 16:31:38.216013 | 2023-08-14 04:40:41.907605 | | 56314 | 2023-07-07 20:48:33.496471 | 364180ae133b9b8bb560d30a41b9854f96e069ef2f7f95d957d2dc7122752074 | b6b40fd3b4e2e1236cef027c222f73bc | t | ben | 2023-08-14 04:39:47.42192 | f | 2023-08-14 04:30:26.764459 | 2 | t | 1 | 2019-11-15 16:31:38.089553 | 2023-07-22 02:14:01.540478 | 2022-05-05 17:39:02.632952 | 2022-05-06 17:38:55.054 | | 0 | 0 | 127.0.0.1 | f | Prime Four | | en | 196 | 127.0.0.1 | f | 2019-11-15 16:31:38.714185 | | | | | 196 | | $pbkdf2-sha256$i=64000,l=32$
CREATE TABLE groups (
id integer NOT NULL,
name character varying NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
automatic boolean DEFAULT false NOT NULL,
user_count integer DEFAULT 0 NOT NULL,
automatic_membership_email_domains text,
primary_group boolean DEFAULT false NOT NULL,
title character varying,
grant_trust_level integer,
incoming_email character varying,
has_messages boolean DEFAULT false NOT NULL,
flair_url character varying,
flair_bg_color character varying,
flair_color character varying,
bio_raw text,
bio_cooked text,
allow_membership_requests boolean DEFAULT false NOT NULL,
full_name character varying,
default_notification_level integer DEFAULT 3 NOT NULL,
visibility_level integer DEFAULT 0 NOT NULL,
public_exit boolean DEFAULT false NOT NULL,
public_admission boolean DEFAULT false NOT NULL,
membership_request_template text,
messageable_level integer DEFAULT 0,
mentionable_level integer DEFAULT 0,
members_visibility_level integer DEFAULT 0 NOT NULL,
publish_read_state boolean DEFAULT false NOT NULL,
flair_icon character varying,
flair_upload_id integer,
smtp_server character varying,
smtp_port integer,
smtp_ssl boolean,
imap_server character varying,
imap_port integer,
imap_ssl boolean,
imap_mailbox_name character varying DEFAULT ''::character varying NOT NULL,
imap_uid_validity integer DEFAULT 0 NOT NULL,
imap_last_uid integer DEFAULT 0 NOT NULL,
email_username character varying,
email_password character varying,
imap_last_error text,
imap_old_emails integer,
imap_new_emails integer,
allow_unknown_sender_topic_replies boolean DEFAULT false NOT NULL,
smtp_enabled boolean DEFAULT false,
smtp_updated_at timestamp without time zone,
smtp_updated_by_id integer,
imap_enabled boolean DEFAULT false,
imap_updated_at timestamp without time zone,
imap_updated_by_id integer,
assignable_level integer DEFAULT 0 NOT NULL,
email_from_alias character varying
); -- users who have either 'admin' or 'moderator' status are added to the automatic "staff" group --
SELECT * FROM groups WHERE id = 1 OR id = 11 OR id = 49;
id | name | created_at | updated_at | automatic | user_count | automatic_membership_email_domains | primary_group | title | grant_trust_level | incoming_email | has_messages | flair_bg_color | flair_color | bio_raw | bio_cooked | allow_membership_requests | full_name | default_notification_level | visibility_level | public_exit | public_admission | membership_request_template | messageable_level | mentionable_level | members_visibility_level | publish_read_state | flair_icon | flair_upload_id | smtp_server | smtp_port | smtp_ssl | imap_server | imap_port | imap_ssl | imap_mailbox_name | imap_uid_validity | imap_last_uid | email_username | email_password | imap_last_error | imap_old_emails | imap_new_emails | allow_unknown_sender_topic_replies | smtp_enabled | smtp_updated_at | smtp_updated_by_id | imap_enabled | imap_updated_at | imap_updated_by_id | assignable_level | email_from_alias
----+---------------+----------------------------+----------------------------+-----------+------------+------------------------------------+---------------+------------+-------------------+----------------+--------------+----------------+-------------+--------------------+---------------------------+---------------------------+---------------------------+----------------------------+------------------+-------------+------------------+-----------------------------+-------------------+-------------------+--------------------------+--------------------+------------+-----------------+-------------+-----------+----------+-------------+-----------+----------+-------------------+-------------------+---------------+----------------+----------------+-----------------+-----------------+-----------------+------------------------------------+--------------+---------------------------+--------------------+--------------+-----------------+--------------------+------------------+------------------
1 | admins | 2019-04-26 22:58:35.997964 | 2021-08-05 19:11:22.699825 | t | 1 | | f | | | | t | | | | | f | | 3 | 1 | f | f | | 99 | 0 | 0 | f | | | | | | | | | | 0 | 0 | | | | | | f | f | | | f | | | 0 |
11 | trust_level_1 | 2019-04-26 22:58:36.033238 | 2021-10-05 19:54:51.043121 | t | 116 | | f | | | | t | | | | | f | | 3 | 1 | f | f | | 0 | 0 | 0 | f | | | | | | | | | | 0 | 0 | | | | | | f | f | | | f | | | 0 |
49 | eurorack | 2019-10-03 17:28:42.323203 | 2022-08-16 19:54:09.223307 | f | 84 | example.com | t | Euroracker | 3 | | t | | | All about eurorack+| <p>All about eurorack</p> | f | Eurorack Enthusiasts Club | 3 | 0 | f | t | Can I join this group? | 99 | 99 | 0 | t | | | | | | | | | | 0 | 0 | | | | | | f | f | 2022-02-11 23:24:28.76631 | 1 | f | | | 0 |
/* group_users joins the groups and users tables */
CREATE TABLE group_users (
id integer NOT NULL,
group_id integer NOT NULL,
user_id integer NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
owner boolean DEFAULT false NOT NULL,
notification_level integer DEFAULT 2 NOT NULL,
first_unread_pm_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
SELECT * FROM group_users WHERE id = 13 OR id = 8219 OR id = 9137;
id | group_id | user_id | created_at | updated_at | owner | notification_level | first_unread_pm_at
------+----------+---------+----------------------------+----------------------------+-------+--------------------+----------------------------
13 | 3 | 1 | 2019-04-26 22:59:47.828533 | 2019-04-26 22:59:47.828533 | f | 2 | 2023-08-14 01:14:54.229593
8219 | 13 | 121 | 2022-04-21 08:15:47.946036 | 2022-04-21 08:15:47.946036 | f | 2 | 2023-07-05 06:49:04.48265
9137 | 49 | 2 | 2022-09-08 17:34:39.290504 | 2022-09-08 17:34:39.290504 | t | 3 | 2020-11-21 02:40:15.868728
CREATE TABLE posts (
id integer NOT NULL,
user_id integer,
topic_id integer NOT NULL,
post_number integer NOT NULL,
raw text NOT NULL,
cooked text NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
reply_to_post_number integer,
reply_count integer DEFAULT 0 NOT NULL,
quote_count integer DEFAULT 0 NOT NULL,
deleted_at timestamp without time zone, -- the application only "soft deletes" posts and topics. Unless explicitly asked to return details about deleted posts or topics, always check that `deleted_at IS NULL` when writing queries related to posts or topics. --
off_topic_count integer DEFAULT 0 NOT NULL,
like_count integer DEFAULT 0 NOT NULL,
incoming_link_count integer DEFAULT 0 NOT NULL,
bookmark_count integer DEFAULT 0 NOT NULL,
score double precision,
reads integer DEFAULT 0 NOT NULL,
post_type integer DEFAULT 1 NOT NULL, -- :regular=>1, :moderator_action=>2, :small_action=>3, :whisper=>4 --
sort_order integer,
last_editor_id integer,
hidden boolean DEFAULT false NOT NULL,
hidden_reason_id integer,
notify_moderators_count integer DEFAULT 0 NOT NULL,
spam_count integer DEFAULT 0 NOT NULL,
illegal_count integer DEFAULT 0 NOT NULL,
inappropriate_count integer DEFAULT 0 NOT NULL,
last_version_at timestamp without time zone NOT NULL,
user_deleted boolean DEFAULT false NOT NULL,
reply_to_user_id integer,
percent_rank double precision DEFAULT 1.0,
notify_user_count integer DEFAULT 0 NOT NULL,
like_score integer DEFAULT 0 NOT NULL,
deleted_by_id integer,
edit_reason character varying,
word_count integer,
version integer DEFAULT 1 NOT NULL,
cook_method integer DEFAULT 1 NOT NULL,
wiki boolean DEFAULT false NOT NULL,
baked_at timestamp without time zone,
baked_version integer,
hidden_at timestamp without time zone,
self_edits integer DEFAULT 0 NOT NULL,
reply_quoted boolean DEFAULT false NOT NULL,
via_email boolean DEFAULT false NOT NULL,
raw_email text,
public_version integer DEFAULT 1 NOT NULL,
action_code character varying,
locked_by_id integer,
image_upload_id bigint
);
SELECT * FROM posts WHERE id = 11094 OR id = 11095 OR id = 11096;
id | user_id | topic_id | post_number | raw | cooked | created_at | updated_at | reply_to_post_number | reply_count | quote_count | deleted_at | off_topic_count | like_count | incoming_link_count | bookmark_count | score | reads | post_type | sort_order | last_editor_id | hidden | hidden_reason_id | notify_moderators_count | spam_count | illegal_count | inappropriate_count | last_version_at | user_deleted | reply_to_user_id | percent_rank | notify_user_count | like_score | deleted_by_id | edit_reason | word_count | version | cook_method | wiki | baked_at | baked_version | hidden_at | self_edits | reply_quoted | via_email | raw_email | public_version | action_code | locked_by_id | image_upload_id | outbound_message_id
-------+---------+----------+-------------+----------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+----------------------------+----------------------+-------------+-------------+------------+-----------------+------------+---------------------+----------------+-------+-------+-----------+------------+----------------+--------+------------------+-------------------------+------------+---------------+---------------------+----------------------------+--------------+------------------+-------------------+-------------------+------------+---------------+-------------+------------+---------+-------------+------+----------------------------+---------------+-----------+------------+--------------+-----------+-----------+----------------+-------------+--------------+-----------------+--------------------------------
11094 | 1 | 1852 | 7 | This is an example of a Discourse post. | <p>This is an example of a Discourse post.</p> | 2023-08-14 04:08:43.430717 | 2023-08-14 04:08:43.430717 | | 0 | 0 | | 0 | 0 | 0 | 0 | 0.2 | 1 | 1 | 7 | 1 | f | | 0 | 0 | 0 | 0 | 2023-08-14 04:08:43.441371 | f | | 0.166666666666667 | 0 | 0 | | | 8 | 1 | 1 | f | 2023-08-14 04:08:43.430685 | 2 | | 0 | f | f | | 1 | | | |
11095 | 2 | 10863 | 11 | This is another example of a Discourse post. | <p>This is another example of a Discourse post.</p> | 2023-08-14 04:11:37.417456 | 2023-08-14 04:11:37.417456 | 5 | 0 | 0 | | 0 | 0 | 0 | 0 | 0.4 | 2 | 1 | 11 | 2 | f | | 0 | 0 | 0 | 0 | 2023-08-14 04:11:37.430459 | f | 121 | 0.8 | 0 | 0 | | | 8 | 1 | 1 | f | 2023-08-14 04:11:37.417417 | 2 | | 0 | f | f | | 1 | | | | discourse/post/11095@127.0.0.1
11096 | 121 | 11047 | 2 | Thanks! I hadn't seen that :slight_smile: | <p>Thanks! I hadn’t seen that <img src="//127.0.0.1:4200/images/emoji/twitter/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> | 2023-08-14 04:13:09.346146 | 2023-08-14 05:17:10.659726 | | 0 | 0 | | 0 | 0 | 0 | 0 | 0.4 | 2 | 1 | 2 | 1 | f | | 0 | 0 | 0 | 0 | 2023-08-14 05:17:10.589855 | f | | 0 | 0 | 0 | | | 7 | 2 | 1 | f | 2023-08-14 05:17:10.659607 | 2 | | 0 | f | f | | 2 | | | | discourse/post/11096@127.0.0.1
CREATE TABLE topics (
id integer NOT NULL,
title character varying NOT NULL,
last_posted_at timestamp without time zone,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
views integer DEFAULT 0 NOT NULL,
posts_count integer DEFAULT 0 NOT NULL,
user_id integer, -- user id the id of the user who created the topic --
last_post_user_id integer NOT NULL,
reply_count integer DEFAULT 0 NOT NULL,
featured_user1_id integer,
featured_user2_id integer,
featured_user3_id integer,
deleted_at timestamp without time zone, -- the application only "soft deletes" posts and topics. Unless explicitly asked to return details about deleted posts or topics, always check that `deleted_at IS NULL` when writing queries related to posts or topics. --
highest_post_number integer DEFAULT 0 NOT NULL,
like_count integer DEFAULT 0 NOT NULL,
incoming_link_count integer DEFAULT 0 NOT NULL,
category_id integer,
visible boolean DEFAULT true NOT NULL,
moderator_posts_count integer DEFAULT 0 NOT NULL,
closed boolean DEFAULT false NOT NULL,
archived boolean DEFAULT false NOT NULL,
bumped_at timestamp without time zone NOT NULL,
has_summary boolean DEFAULT false NOT NULL,
archetype character varying DEFAULT 'regular'::character varying NOT NULL, -- archetype can be set to either 'regular' or 'private_message' --
featured_user4_id integer,
notify_moderators_count integer DEFAULT 0 NOT NULL,
spam_count integer DEFAULT 0 NOT NULL,
pinned_at timestamp without time zone,
score double precision,
percent_rank double precision DEFAULT 1.0 NOT NULL,
subtype character varying,
slug character varying,
deleted_by_id integer,
participant_count integer DEFAULT 1,
word_count integer,
excerpt character varying,
pinned_globally boolean DEFAULT false NOT NULL,
pinned_until timestamp without time zone,
fancy_title character varying,
highest_staff_post_number integer DEFAULT 0 NOT NULL,
featured_link character varying,
reviewable_score double precision DEFAULT 0.0 NOT NULL,
image_upload_id bigint,
slow_mode_seconds integer DEFAULT 0 NOT NULL,
bannered_until timestamp without time zone,
external_id character varying,
CONSTRAINT has_category_id CHECK (((category_id IS NOT NULL) OR ((archetype)::text <> 'regular'::text))),
CONSTRAINT pm_has_no_category CHECK (((category_id IS NULL) OR ((archetype)::text <> 'private_message'::text)))
);
SELECT * FROM topics WHERE id = 1852 OR id = 10863 OR id = 11047;
id | title | last_posted_at | created_at | updated_at | views | posts_count | user_id | last_post_user_id | reply_count | featured_user1_id | featured_user2_id | featured_user3_id | deleted_at | highest_post_number | like_count | incoming_link_count | category_id | visible | moderator_posts_count | closed | archived | bumped_at | has_summary | archetype | featured_user4_id | notify_moderators_count | spam_count | pinned_at | score | percent_rank | subtype | slug | deleted_by_id | participant_count | word_count | excerpt | pinned_globally | pinned_until | fancy_title | highest_staff_post_number | featured_link | reviewable_score | image_upload_id | slow_mode_seconds | bannered_until | external_id
-------+-------------------------------------+----------------------------+----------------------------+----------------------------+-------+-------------+---------+-------------------+-------------+-------------------+-------------------+-------------------+------------+---------------------+------------+---------------------+-------------+---------+-----------------------+--------+----------+----------------------------+-------------+-----------------+-------------------+-------------------------+------------+-----------+-------------------+--------------+--------------+-------------------------------------+---------------+-------------------+------------+-----------------------------------------------------------------------------------+-----------------+--------------+-------------------------------------+---------------------------+---------------+------------------+-----------------+-------------------+----------------+-------------
1852 | Ask Me Anything | 2023-08-14 04:08:43.430717 | 2020-05-04 22:11:50.813596 | 2023-08-14 05:25:00.249902 | 2 | 3 | 1 | 1 | 0 | | | | | 7 | 0 | 2 | 3 | t | 4 | f | f | 2023-08-14 04:08:43.430717 | f | regular | | 0 | 0 | | 0.914285714285714 | 1 | | ask-me-anything | | 1 | 157 | The AMA with @sally will be held on May 8th. Start sending in your questions now. | f | | Ask Me Anything | 7 | | 0 | | 0 | |
10863 | Post the last picture on your phone | 2023-08-14 04:11:37.417456 | 2022-01-25 21:42:52.514124 | 2023-08-14 05:22:30.373683 | 18 | 5 | 2 | 2 | 3 | 121 | 1 | | | 11 | 4 | 7 | 14 | t | 0 | f | f | 2023-08-14 04:11:37.417456 | f | regular | | 0 | 0 | | 6.54545454545455 | 1 | | post-the-last-picture-on-your-phone | | 3 | 150 | This is a test. This should go to the review queue | f | | Post the last picture on your phone | 11 | | 70.75 | 445 | 0 | |
11047 | Have you seen this post? | 2023-08-14 04:13:09.346146 | 2022-05-12 22:26:39.280698 | 2023-08-14 05:16:41.106722 | 3 | 2 | 1 | 121 | 0 | | | | | 2 | 0 | 0 | | t | 0 | f | f | 2023-08-14 05:17:10.695009 | f | private_message | | 0 | 0 | | 0.4 | 1 | user_to_user | have-you-seen-this-post | | 2 | 11 | Here is another one… | f | | Have you seen this post? | 2 | | 0 | | 0 | |
CREATE TABLE categories (
id integer NOT NULL,
name character varying(50) NOT NULL,
color character varying(6) DEFAULT '0088CC'::character varying NOT NULL,
topic_id integer,
topic_count integer DEFAULT 0 NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
user_id integer NOT NULL,
topics_year integer DEFAULT 0,
topics_month integer DEFAULT 0,
topics_week integer DEFAULT 0,
slug character varying NOT NULL,
description text,
text_color character varying(6) DEFAULT 'FFFFFF'::character varying NOT NULL,
read_restricted boolean DEFAULT false NOT NULL,
auto_close_hours double precision,
post_count integer DEFAULT 0 NOT NULL,
latest_post_id integer,
latest_topic_id integer,
"position" integer,
parent_category_id integer,
posts_year integer DEFAULT 0,
posts_month integer DEFAULT 0,
posts_week integer DEFAULT 0,
email_in character varying,
email_in_allow_strangers boolean DEFAULT false,
topics_day integer DEFAULT 0,
posts_day integer DEFAULT 0,
allow_badges boolean DEFAULT true NOT NULL,
name_lower character varying(50) NOT NULL,
auto_close_based_on_last_post boolean DEFAULT false,
topic_template text,
contains_messages boolean,
sort_order character varying,
sort_ascending boolean,
uploaded_logo_id integer,
uploaded_background_id integer,
topic_featured_link_allowed boolean DEFAULT true,
all_topics_wiki boolean DEFAULT false NOT NULL,
show_subcategory_list boolean DEFAULT false,
num_featured_topics integer DEFAULT 3,
default_view character varying(50),
subcategory_list_style character varying(50) DEFAULT 'rows_with_featured_topics'::character varying,
default_top_period character varying(20) DEFAULT 'all'::character varying,
mailinglist_mirror boolean DEFAULT false NOT NULL,
minimum_required_tags integer DEFAULT 0 NOT NULL,
navigate_to_first_post_after_read boolean DEFAULT false NOT NULL,
search_priority integer DEFAULT 0,
allow_global_tags boolean DEFAULT false NOT NULL,
reviewable_by_group_id integer,
read_only_banner character varying,
default_list_filter character varying(20) DEFAULT 'all'::character varying,
allow_unlimited_owner_edits_on_first_post boolean DEFAULT false NOT NULL,
default_slow_mode_seconds integer
);
SELECT * FROM categories WHERE id = 3 OR id = 16 OR id = 42;
id | name | color | topic_id | topic_count | created_at | updated_at | user_id | topics_year | topics_month | topics_week | slug | description | text_color | read_restricted | auto_close_hours | post_count | latest_post_id | latest_topic_id | position | parent_category_id | posts_year | posts_month | posts_week | email_in | email_in_allow_strangers | topics_day | posts_day | allow_badges | name_lower | auto_close_based_on_last_post | topic_template | contains_messages | sort_order | sort_ascending | uploaded_logo_id | uploaded_background_id | topic_featured_link_allowed | all_topics_wiki | show_subcategory_list | num_featured_topics | default_view | subcategory_list_style | default_top_period | mailinglist_mirror | minimum_required_tags | navigate_to_first_post_after_read | search_priority | allow_global_tags | reviewable_by_group_id | read_only_banner | default_list_filter | allow_unlimited_owner_edits_on_first_post | default_slow_mode_seconds | uploaded_logo_dark_id
----+------------------+--------+----------+-------------+----------------------------+----------------------------+---------+-------------+--------------+-------------+------------------+-------------------------------------------------------------------------------------------+------------+-----------------+------------------+------------+----------------+-----------------+----------+--------------------+------------+-------------+------------+----------+--------------------------+------------+-----------+--------------+------------------+-------------------------------+----------------+-------------------+------------+----------------+------------------+------------------------+-----------------------------+-----------------+-----------------------+---------------------+--------------+---------------------------+--------------------+--------------------+-----------------------+-----------------------------------+-----------------+-------------------+------------------------+------------------+---------------------+-------------------------------------------+---------------------------+-----------------------
3 | Staff | E45735 | 2 | 16 | 2019-04-26 22:58:38.813759 | 2023-02-16 08:35:51.424024 | -1 | 0 | 0 | 0 | staff | Private category for staff discussions. Topics are only visible to admins and moderators. | FFFFFF | t | | 23 | 11094 | 11250 | 41 | | 1 | 0 | 0 | | f | 0 | 0 | t | staff | f | | | | | | | t | f | f | 3 | | rows_with_featured_topics | all | f | 0 | f | 0 | f | | | all | f | |
16 | customer support | F7941D | 277 | 13 | 2019-07-17 20:18:13.584715 | 2023-08-11 20:50:35.548498 | 1 | 1 | 0 | 0 | customer-support | This description will appear on the categories page. | FFFFFF | f | 720 | 68 | 11087 | 11236 | 0 | | 10 | 7 | 0 | | f | 0 | 0 | f | customer support | f | | | | | 689 | | t | f | f | 4 | | rows_with_featured_topics | all | f | 0 | f | 0 | f | | | all | f | |
42 | eurorack | 0088CC | 584 | 30 | 2019-10-03 17:29:33.782372 | 2023-08-13 21:35:09.514998 | 1 | 1 | 0 | 0 | eurorack | All about Eurorack synths. | FFFFFF | f | | 142 | 11091 | 11183 | 1 | | 15 | 3 | 3 | | f | 0 | 3 | t | eurorack | f | | | posts | | | | t | f | f | 4 | latest | rows_with_featured_topics | all | f | 2 | t | 0 | f | | | all | f | |
CREATE TABLE tags (
id integer NOT NULL,
name character varying NOT NULL,
topic_count integer DEFAULT 0 NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
pm_topic_count integer DEFAULT 0 NOT NULL,
target_tag_id integer,
description character varying
);
SELECT * FROM tags WHERE id = 183 OR id = 184 OR id = 185;
id | name | created_at | updated_at | pm_topic_count | target_tag_id | description | public_topic_count | staff_topic_count
-----+-------------+----------------------------+----------------------------+----------------+---------------+-------------+--------------------+-------------------
183 | photos | 2023-08-14 05:22:30.326838 | 2023-08-14 05:22:30.326838 | 0 | | | 1 | 1
184 | meetup | 2023-08-14 05:25:00.227547 | 2023-08-14 05:25:00.227547 | 0 | | | 0 | 1
185 | icebreakers | 2023-08-14 06:18:39.214459 | 2023-08-14 06:18:39.214459 | 0 | | | 1 | 1
CREATE TABLE topic_tags (
id integer NOT NULL,
topic_id integer NOT NULL,
tag_id integer NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
SELECT * FROM topic_tags WHERE id = 1005 OR id = 1006 OR id = 1007;
id | topic_id | tag_id | created_at | updated_at
------+----------+--------+----------------------------+----------------------------
1005 | 10863 | 183 | 2023-08-14 05:22:30.360668 | 2023-08-14 05:22:30.360668
1006 | 1852 | 184 | 2023-08-14 05:25:00.237298 | 2023-08-14 05:25:00.237298
1007 | 10863 | 185 | 2023-08-14 06:18:39.240753 | 2023-08-14 06:18:39.240753
CREATE TABLE user_actions (
id integer NOT NULL,
action_type integer NOT NULL, -- :like=>1 (when a user likes a post), :was_liked=>2 (when a user's post is liked), :new_topic=>4, :reply=>5, :response=>6, :mention=>7, :quote=>9, :edit=>11, :new_private_message=>12, :got_private_message=>13, :solved=>15, :assigned=>16 --
user_id integer NOT NULL,
target_topic_id integer,
target_post_id integer,
target_user_id integer,
acting_user_id integer,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
SELECT * FROM user_actions WHERE id = 19928 OR id = 19929 OR id = 19931;
/*
In the first example below, the user with the id 1 has liked (action_type: 1) the post with the id 11100. Because the user with the id 1 took the action, 1 is set as the value of the acting_user_id column. Because the entry is recording that this user has performed a "like" action, their user id (1) is also set in the entry's user_id column.
Here's an example query that would return the number of times the user with id: 1 has liked other user's posts: `SELECT COUNT(user_id) AS number_of_likes_given FROM user_actions WHERE action_type = 1 AND user_id = 1;`
In the second example below, the user with the id 121 has had their post (id 11100) liked by another user (action_type: 2). The entry's user_id is set to 121 because that's the id of the user who has had their post liked. The entry's acting_user_id column is set to 1 because that is the user who liked the post.
Here's an example query that returns the number of times the user with id 121 has had their posts liked by other users: `SELECT COUNT(user_id) AS number_of_likes_received FROM user_actions WHERE action_type = 2 AND user_id = 121;`
Here's an example query that returns the number of times the user with id 121 has had their posts liked by the user with id: 1: `SELECT COUNT(user_id) AS number_of_likes_received_from_user_1 FROM user_actions WHERE action_type = 2 AND user_id = 121 AND acting_user_id = 1;`
In the third example, the user with the id 121 has been mentioned (action_type: 7) in the post (id 11101) by the user with the id 2. The entry's user_id is set to 121 because that is the id of the user who was mentioned. The entry's acting_user_id is set to 2 because that is the id of the user who created the mention.
Here's an example that returns the number of times the user with id 121 has been mentioned by any users: `SELECT COUNT(user_id) AS number_of_mentions_received FROM user_actions WHERE action_type = 7 AND user_id = 121;`
Here's an example query that returns the number of times the user with id 121 has been mentioned by the user with id 2: `SELECT COUNT(user_id) AS number_of_mentions_received_from_user_2 FROM user_actions WHERE action_type = 7 AND user_id = 121 AND acting_user_id = 2;`
Here's an example query that returns the number of times the user with id 121 has been mentioned in the topic with the id 7282: `SELECT COUNT(user_id) AS number_of_mentions_received_in_topic FROM user_actions WHERE action_type = 7 AND user_id = 121 AND target_topic_id = 7282;`
*/
id | action_type | user_id | target_topic_id | target_post_id | target_user_id | acting_user_id | created_at | updated_at
-------+-------------+---------+-----------------+----------------+----------------+----------------+----------------------------+----------------------------
19928 | 1 | 1 | 7282 | 11100 | | 1 | 2023-08-14 07:47:49.520171 | 2023-08-14 07:47:49.651056
19929 | 2 | 121 | 7282 | 11100 | | 1 | 2023-08-14 07:47:49.520171 | 2023-08-14 07:47:49.671757
19931 | 7 | 121 | 7282 | 11101 | | 2 | 2023-08-14 08:00:05.877537 | 2023-08-14 08:00:05.877537
CREATE TABLE polls (
id bigint NOT NULL,
post_id bigint,
name character varying DEFAULT 'poll'::character varying NOT NULL,
close_at timestamp without time zone,
type integer DEFAULT 0 NOT NULL,
status integer DEFAULT 0 NOT NULL,
results integer DEFAULT 0 NOT NULL,
visibility integer DEFAULT 0 NOT NULL,
min integer,
max integer,
step integer,
anonymous_voters integer,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
chart_type integer DEFAULT 0 NOT NULL, -- {"bar"=>0, "pie"=>1} --
groups character varying,
title character varying
);
SELECT * FROM polls WHERE id = 71 OR id = 72 OR id = 74;
id | post_id | name | close_at | type | status | results | visibility | min | max | step | anonymous_voters | created_at | updated_at | chart_type | groups | title
----+---------+------+---------------------+------+--------+---------+------------+-----+-----+------+------------------+----------------------------+----------------------------+------------+---------------+-------------------------------------------
71 | 11097 | poll | 2023-08-20 07:00:00 | 0 | 0 | 0 | 1 | | | | | 2023-08-14 06:38:10.96388 | 2023-08-14 06:38:10.96388 | 0 | trust_level_2 | Who took the best picture?
72 | 11098 | poll | 2023-09-10 07:00:00 | 0 | 0 | 0 | 1 | | | | | 2023-08-14 06:40:36.925762 | 2023-08-14 06:40:36.925762 | 1 | staff | Who should we invite to our next AMA?
74 | 11100 | poll | 2023-08-27 07:00:00 | 1 | 0 | 0 | 0 | 1 | 2 | | | 2023-08-14 06:48:27.498764 | 2023-08-14 06:48:27.498764 | 0 | eurorack | What are your favourite Eurorack modules?
CREATE TABLE poll_options (
id bigint NOT NULL,
poll_id bigint,
digest character varying NOT NULL,
html text NOT NULL,
anonymous_votes integer,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
SELECT * FROM poll_options WHERE id = 271 OR id = 274 OR id = 280;
id | poll_id | digest | html | anonymous_votes | created_at | updated_at
-----+---------+----------------------------------+----------------+-----------------+----------------------------+----------------------------
271 | 71 | 5c6c2c880d86e5a0d9f0924a7ffd9629 | Sally | | 2023-08-14 06:38:10.975263 | 2023-08-14 06:38:10.975263
274 | 72 | 2654933188fb6bd444b6df4cc39fd908 | Dangerous Dave | | 2023-08-14 06:40:36.930354 | 2023-08-14 06:40:36.930354
280 | 74 | f2e5462d97476629719e607dc80a9619 | Maths | | 2023-08-14 06:48:27.502673 | 2023-08-14 06:48:27.502673
CREATE TABLE poll_votes (
poll_id bigint,
poll_option_id bigint,
user_id bigint,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
SELECT * FROM poll_votes WHERE poll_id = 71;
poll_id | poll_option_id | user_id | created_at | updated_at
---------+----------------+---------+----------------------------+----------------------------
71 | 270 | 2 | 2023-08-14 06:59:00.382873 | 2023-08-14 06:59:00.382873
71 | 271 | 121 | 2023-08-14 07:02:57.364892 | 2023-08-14 07:02:57.364892
71 | 271 | 1 | 2023-08-14 07:03:36.464304 | 2023-08-14 07:03:36.464304
/* Discourse database documentation end */
It covers the users, groups, group_users, posts, topics, categories, tags, topic_tags, user_actions, polls, poll_options, and poll_votes tables. It’s currently at 1150 tokens, so it should be able to double its size without causing issues. Note that if you copy it into a ChatGPT chat input, you’ll need to paste it into two separate inputs - the character limit on a chat input is less than the token limit for a chat session.
I added fairly detailed comments above the example user_actions queries. With those examples, ChatGPT is doing a good job in answering questions about likes given, likes received, etc. Previously it had been struggling with that. I suspect there are a few tables that would need a similar approach.
After having sent the documentation, the following prompts are helpful:
Example prompts
When I ask you start a query with a ‘query period CTE’, I want the query to start with exactly this SQL (including the comment):
--[params]
-- string :query_interval = 1 week
-- date :start_date
-- date :end_date
WITH query_periods AS (
SELECT
generate_series(:start_date, :end_date, :query_interval::interval)::date AS period_start,
(generate_series(:start_date, :end_date, :query_interval::interval)::date + :query_interval::interval - INTERVAL '1 DAY')::date AS period_end
)
The Data Explorer plugin allows paramters to be added to its queries. Parameters that are used in queries need to appear in a comment at the top of the query in this form:
--[params]
--param_type :param_name
The available param types are:
int,bigint,boolean,string,date,time,datetime,double,user_id,post_id,topic_id,category_id,group_id,badge_id,int_list,string_list,user_list
Here is an example:
--[params]
-- string :action_type
An optional default value can be supplied for a parameter. For example:
--[params]
--string :action_type = like
I created the “query_period CTE” prompt because if I didn’t specifically tell ChatGPT how to create the query_period CTE, it was coming up will all sorts of solutions, some better than others. With the prompt, it adds the exact code I give it, then builds queries on top of it without any problems. Interestingly, when I tried to add details about how to create a “query period CTE” to the initial documentation that I sent ChatGPT, it would just ignore the instructions. For some reason sending it as a separate prompt makes a difference.
Prompts describing how Discourse “soft deletes” topics and posts are also helpful. After letting ChatGPT know about the need to check that deleted_at IS NOT NULL for queries related to topics and posts, it consistently applies that to all queries.
Telling ChatGPT to leave off the semicolon at the end of the queries is kind of hopeless. It remembers for a couple of queries, then goes back to adding the semicolon. That seems like a minor detail.
My initial hope of having a perfect query returned from a natural language question was a bit ambitious. It makes mistakes, and so do I. At least in the short term, I think the best way to integrate ChatGPT with the Data Explorer plugin would be to initiate a PM with ChatGPT. A basic description of the database could be sent when the PM is created. Then a selection of prompts could be made available via the UI. For example, a prompt for parameterizing a query, or a prompt for adding details about a seldom used table.
My suspicion is that this could be very helpful to someone who knows a bit of SQL, but possibly it could also be implemented in a way that would help people who are new to SQL get up to speed a lot faster than they would on their own. I learned this wonderful trick today:
WITH post_type_mapping AS (
SELECT 'regular' AS type, 1 AS post_type
UNION ALL
SELECT 'moderator_action' AS type, 2 AS post_type
UNION ALL
SELECT 'small_action' AS type, 3 AS post_type
UNION ALL
SELECT 'whisper' AS type, 4 AS post_type
)
...
JOIN post_type_mapping m ON :post_type = m.type
WHERE p.post_type = m.post_type
あなたの依存症を助長していないことを願っています。
研究論文を読むかどうかはわかりませんが、今日、あなたが正しい道を歩んでおり、自然言語クエリから始めて有効なSQLと結果を生成するという目標を達成するための新しい道筋を示せる可能性があることを強化する別の論文に出くわしました。
この論文は数学の問題に関するものですが、数学はSQLと同様に単なる式であるため、一方の形式の式をもう一方の形式に置き換えるだけで理にかなうはずです。同様のアイデアを持つ多くの関連論文があるので、この論文を権威あるものとは考えないでください。
「Aojun Zhoun、Ke Wang、Zimu Lu、Weikang Shi、Sichun Luo、Zipeng Qin、Shaoqing Lu、Anya Jia、Linqi Song、Mingjie Zhan、およびHongsheng Liによる「Solving Challenging Math Word Problems Using Gpt-4 Code Interpreter With Code-Based Self-Verification」」(pdf)
もう一つ、あなたのお役に立つかもしれないアイデアがあります。これは少々突飛に聞こえるかもしれませんが、私はPrologコード、特にWebページを生成するためにこれを使用しました。
問題は、生成AIがSQLを理解するのが難しいことにあるのかもしれません。SQLは宣言型言語であり、生成AIがプログラミング言語で成功を収めているのは、JavaScript、Python、Javaなどの少数の命令型言語に関する大規模なトレーニングセットに基づいているからです。しかし、トランスフォーマーに基づいており、トランスフォーマーはもともと英語からドイツ語への翻訳のために開発されたと記憶していますが、よくトレーニングされたプログラミング言語との間で翻訳するのに優れています。したがって、最初にSQLを要求する代わりに、Pythonなどのよくトレーニングされたプログラミング言語に問題を解決するコードを要求し、次に生成AIにPythonをSQLに翻訳させて、それが機能するかどうかを確認してください。私はこれを試すつもりはありませんが、あなたがこれを楽しむようなので、どうぞお試しください。また、もしこれを試すなら、ぜひフィードバックをお願いします。発見したことをぜひ知りたいです。 ![]()
それはタイプミスですか?
WHERE poll_id = 74 は WHERE poll_id = 71 になるべきですか?
プロンプト全体を確認しませんでしたが、クエリの結果がどのようになるかの例が含まれているかどうかを確認していました。言い換えれば、テーブルの値の例は示されましたが、プロンプトの期待される結果の例は見られませんでした。おそらく見落としたのでしょう。期待される結果は、SQLが正しいかどうかを検証するために使用できます。
提案:
Discourse database prompt の例では、IDに 1 を使用することが複数のテーブルで使用されています。人間は 1 がフィールドとテーブルのコンテキストでのみ意味を持つことを理解しますが、AIはこれを理解しないため、AIが選択する機会を与える可能性があります。したがって、提案として Discourse database prompt を変更して、各IDに異なる数値を使用してください。
さらに一歩進んで、OpenAI Tokenizerページを使用して、各例テーブルのすべての値が単一のトークンであることを確認してください。それらのいくつかを単語、あるいはそれ以上に悪い文字列のままにしておきたいかもしれませんが、AIは本当にそれを気にしますか?複数のトークンを持つ値は、より多くのバリエーションと可能性のある幻覚につながるのでしょうか?
間違いです。修正します。関連する他の投票テーブルの結果を取得するために、71 でクエリを再実行したと思います。
ブログ記事で推奨されている、すべての SELECT クエリを実行する方法から逸脱しました。
SELECT * FROM polls LIMIT 3;
これは、開発データベースに匿名ユーザーと削除された投稿がたくさんあるためです。その方がより一貫性のある結果が得られると考えましたが、新しいデータベースでプロンプトを再実行し、SELECT ステートメントを単純化してみます。
はい、すべての例で 3 人のユーザーを使用しています。ID は 1、2、121 なので、これらの値は頻繁に繰り返されます。一貫性のあるデータを示すのが最善だと想定していました。いくつかの異なるアプローチを試して、何が最も効果的かを確認します。
ブログ記事で提案されているもう 1 つのアプローチは、プロンプトで設定する列を制限することです。それは魅力的ですが、多くのエラーを導入するリスクがあり、維持が困難になります。
私が 見ていると思う パターンは、複雑なクエリを要求してセッションを開始すると、ChatGPT が混乱することです。混乱を乗り越えさせると、セッションの残りの部分で結果は非常に良好になります。もう 1 つうまくいくと思われるアプローチは、単純なクエリから始めて、そこからより複雑なクエリに進むことです。それが実際のパターンなのか、それとも成功率が実際よりもランダムなのかはわかりません。
現状では、SQL と Discourse データベースに既に精通している人にとっては役立つようです。どちらについてもあまり知らない人にとって役立つレベルに到達させたいと思います。
ChatGPT-4 でもテストしています。おそらくより良い結果が得られるでしょうが、使用するのが less fun になるかもしれません。ChatGPT-3.5 ははるかに高速です。
数十年前にデータベースを学んだとき、SQLを学ぶだけでも混乱しましたが、その後、Microsoft Accessのクエリビルダーを使いました。それはテーブルをドラッグ&ドロップし、Visioのように線でテーブルフィールド同士を接続するもので、SQLを生成してくれました。
同様のツール、こちらからの画像
DiscourseがSQL構築のためのそのようなツールを作成するとは期待しませんが、接続されたテーブルのそのような画像をフィードバックとして生成するためにAIを利用することは可能かもしれません。
このビデオで言及されているように、まずGPT-4で正しい結果を作成し、次に速度のためにGPT-3.5でカスタマイズします。
