Discourse AI + Data Explorer?

エッジケースの例をいくつか教えていただけますか?

「いいね!」 1

はい、来週また別のラウンドを予定しています。共有したリポジトリにある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でのこのクエリ作成の全会話はこちらで確認できます:

「いいね!」 3

@sam 上記のような完全なスキーマ(申し訳ありませんが、これをどこで入手できるのか、またこの形式で入手する方法がわかりません)と、langchain およびベクトルデータベースを使用して、ドキュメントを ChatGPT に送信する 前に 正しく処理し、さらに Data Explorer の使用に関するドキュメントがあれば、このプロセスはほぼ魔法に近いものになると確信しています。

ベクトルDBを試して類似の例をフィードしましたが、それはあまりにも強く誘導しすぎます。魔法のような効果を得るには、おそらく1000個の非常に近い例が必要になるでしょう。

「いいね!」 1

エンジニアにも試してもらいます。私たちはこれらをかなり迅速に生成するための「ファクトリー」のようなものを作りました。

この形式のすべてのデータベーススキーマの完全かつ網羅的なドキュメントを入手できる場所はありますか?

# == 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
「いいね!」 1

その形式はトークン効率が非常に悪いですが、データエクスプローラーのpgスキーマテーブルからクエリで取得できます :slight_smile:

「いいね!」 2

ハハ、わかりました。彼に確認してもらいます。言ったように、私はこれ以上深く追求する人間ではありません。もしそうなら、こんな質問はしていないでしょう!

「いいね!」 1

何かを機能させたいのですが、これは非常に難しい問題です

「いいね!」 3

これは単なるアイデアであり、試したことはありません。

IMOで必要とされるクエリは、職務に基づいた使用法に分解できます。

  • モデレーター
  • 管理者
  • 開発者

したがって、必要とされるテーブルは、徐々に大きくなるセットにグループ化でき、最小のセットはモデレーターに必要なテーブルです。

現在、モデレーターが必要とするデータの多くは、特定の列が必要なテーブルの共通結合に基づいています。したがって、ビューが必要です。

スキーマ全体ではなく共通ビューを使用する場合、多くのプロンプトでスキーマ全体ではなくビューを渡すだけで済むため、LLMが可能なソリューションを生成するのがはるかに簡単になる可能性があります。

お役に立てば幸いです。


はるかに難しいクエリについては、そのようなクエリが必要だと知っているなら、クエリを構築するのに十分な知識がある可能性が高いです。

「いいね!」 1

それを試しました。結果はバラバラです。興味深い実験は、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の制限
  1. 階層クエリ: 再帰的な関係のような階層的なデータ構造を含むクエリは複雑になる可能性があります。例えば、カテゴリ階層内の親-子関係をクエリすることなどです。
  2. 時間的クエリ: 履歴トレンドの計算や特定の時間間隔でのデータの分析など、時間ベースのデータを含むクエリは、より複雑なSQL構文が必要になる場合があります。
  3. ウィンドウ関数: 以前のクエリでウィンドウ関数を使用しましたが、複雑な分析タスクのためのウィンドウ関数のより高度な使用は困難な場合があります。
  4. 地理空間クエリ: 空間データベースや、近くの場所や複雑な空間関係の検索などの地理データに基づいたクエリは、複雑になる可能性があります。
  5. 複雑な集計: 複数のグループ化レベルと計算を含む高度な集計は、より複雑なSQL知識が必要になる場合があります。
  6. 最適化クエリ: インデックス、クエリチューニング、パフォーマンス改善を含む、高度に最適化されたクエリの作成は複雑になる可能性があります。
  7. カスタムアルゴリズム: クエリロジックの複雑さにより、SQLクエリ内にカスタムアルゴリズムまたはロジックを実装することは困難な場合があります。
  8. 高度なJOIN: 複雑なJOIN条件や複数のJOINの結合は、慎重な検討と、より複雑なSQL構文が必要になる場合があります。
  9. サブクエリと相関サブクエリ: サブクエリは処理できますが、非常に複雑または深くネストされたサブクエリはより困難になる可能性があります。
  10. ピボットとアンピボット: データの幅広形式と縦長形式間の変換(ピボットとアンピボット)は、特定のシナリオで複雑になる可能性があります。

問題が発生しているのは、データベーススキーマ全体を曖昧にすることです。例えば、user_actions テーブルにアノテーションを付ける方法を見つけることです。その action_type コードの定義を提供するだけでは不十分です。user_idtarget_user_idacting_user_id について推測し始めます。

最も一般的に要求されるクエリは、データベースのほとんどのテーブルや列を使用しません。データエクスプローラーにAIを追加する場合、「基本」モードと「高度」モードを検討する価値があるかもしれません。基本モードは、ほとんどのユースケースをカバーするプロンプトを提供できます。高度モードでは、ユーザーがプロンプトに設定する情報を選択できます。

GPT-3.5が正常にクエリを作成できるようにするために、メタに対するクエリの要求から逆算して、プロンプトに何を提供する必要があるかを確認するのは興味深いかもしれません。

「いいね!」 3

まずgptにどのテーブルが関連しているかを判断させ、次にsqlを生成する第二段階に進むというlangchainのアプローチが役立つ可能性があります。

「いいね!」 3

当社の製品では、現在LangChainを使用する独自のインプリメンテーションを採用しています。再利用可能なファクトリを構築しましたので、近いうちにリードエンジニアに試してもらう予定です。

しかし、前述したように、これまでの結果には非常に満足しています。まるで、私に代わって用事をこなしてくれるアシスタントがいるようなものです。まだ数回のやり取りが必要ですが、現時点でも時間とお金を大幅に節約できます。

「いいね!」 2

FYI

「いいね!」 2

これは非常に中毒性があります。「LLM と SQL」に関するブログ投稿と、少しの試行錯誤を基に、Discourse データベースの部分的な説明を含むこのプロンプトを作成しました:

Discourse データベースのプロンプト
/* Discourse database documentation start */ と /* Discourse database documentation end */ コメントの間のテキストには、Discourse フォーラムアプリケーションの PostgreSQL データベースに関する詳細が含まれています。
すべてのテーブルと列は `CREATE TABLE` 文で定義されています。各 `CREATE TABLE` 文に続くサンプルクエリにも注意してください。いくつかの追加の重要な詳細は、
インライン (`-- --`) および複数行 (`/* */`) コメントに含まれています。この情報を送信した後、Discourse Data Explorer プラグインで実行するいくつかのクエリを作成するように依頼します。これらのクエリを作成するために必要なすべてのテーブルと列は、
私が送信した `CREATE TABLE` 文に含まれています。

/* Discourse database documentation start */

CREATE TABLE users (
    id integer NOT NULL, -- アプリケーションには「本番」ユーザーの概念があります。「本番」ユーザーとは、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
); -- 'admin' または 'moderator' ステータスをいずれか持つユーザーは、自動的な "staff" グループに追加されます --

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 は groups テーブルと users テーブルを結合します */
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, -- アプリケーションは投稿やトピックを「論理的に削除(soft delete)」するのみです。削除された投稿やトピックの詳細を返すように明示的に要求されない限り、投稿やトピックに関連するクエリを作成する際は常に `deleted_at IS NULL` をチェックしてください。 --
    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, -- トピックを作成したユーザーのID --
    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, -- アプリケーションは投稿やトピックを「論理的に削除(soft delete)」するだけです。削除された投稿やトピックの詳細を返すよう明示的に要求されない限り、投稿やトピックに関連するクエリを作成する際は常に `deleted_at IS NULL` をチェックしてください。 --
    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 は 'regular' または '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 (ユーザーが投稿に「いいね」した場合), :was_liked=>2 (ユーザーの投稿に「いいね」された場合), :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;
/*
以下の最初の例では、ID 1 のユーザーが ID 11100 の投稿に「いいね」(action_type: 1)をしています。ID 1 のユーザーがアクションを実行したため、acting_user_id 列の値として 1 が設定されます。このエントリがユーザーが「いいね」アクションを実行したことを記録しているため、user_id 列にもそのユーザーの ID (1) が設定されます。
以下は、ID 1 のユーザーが他のユーザーの投稿に「いいね」した回数を返すクエリの例です:`SELECT COUNT(user_id) AS number_of_likes_given FROM user_actions WHERE action_type = 1 AND user_id = 1;`

以下の2番目の例では、ID 121 のユーザーの投稿(ID 11100)が別のユーザーから「いいね」されています(action_type: 2)。エントリの user_id は 121 に設定されており、これは投稿に「いいね」されたユーザーの ID です。エントリの acting_user_id 列は 1 に設定されており、これは投稿に「いいね」したユーザーです。
以下は、ID 121 のユーザーの投稿が他のユーザーから「いいね」された回数を返すクエリの例です:`SELECT COUNT(user_id) AS number_of_likes_received FROM user_actions WHERE action_type = 2 AND user_id = 121;`
以下は、ID 121 のユーザーの投稿が 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;`

3番目の例では、ID 121 のユーザーが ID 2 のユーザーによって投稿(ID 11101)でメンションされています(action_type: 7)。エントリの user_id は 121 に設定されており、これはメンションされたユーザーの ID です。エントリの acting_user_id は 2 に設定されており、これはメンションを作成したユーザーの ID です。
以下は、ID 121 のユーザーがどのユーザーからでもメンションされた回数を返す例です:`SELECT COUNT(user_id) AS number_of_mentions_received FROM user_actions WHERE action_type = 7 AND user_id = 121;`
以下は、ID 121 のユーザーが 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;`
以下は、ID 121 のユーザーが 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 */

これは usersgroupsgroup_userspoststopicscategoriestagstopic_tagsuser_actionspollspoll_options、および poll_votes テーブルをカバーしています。現在は 1150 トークンなので、問題を引き起こすことなくサイズを2倍にできるはずです。なお、これを ChatGPT のチャット入力にコピーする場合、2つの別々の入力に貼り付ける必要があります。チャット入力の文字制限は、チャットセッションのトークン制限よりも少ないためです。

例の user_actions クエリの前にかなり詳細なコメントを追加しました。これらの例のおかげで、ChatGPT は「いいね」を与えた回数や「いいね」を受けた回数などに関する質問にうまく答えています。以前はそこでの処理に苦労していました。同様のアプローチが必要なテーブルがいくつかあると思われます。

ドキュメントを送信した後、以下のプロンプトが役立ちます。

プロンプトの例

「クエリ期間 CTE でクエリを開始してください」と尋ねた場合、クエリは以下の SQL(コメントを含む)から正確に開始されるようにしてください:

--[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
)

Data Explorer プラグインはクエリにパラメータを追加できるようにしています。クエリで使用されるパラメータは、この形式でクエリの上部のコメントに表示する必要があります:

--[params]
--param_type :param_name

使用可能なパラメータタイプは:intbigintbooleanstringdatetimedatetimedoubleuser_idpost_idtopic_idcategory_idgroup_idbadge_idint_liststring_listuser_list です。
以下は例です:

--[params]
-- string :action_type

パラメータにオプションのデフォルト値を指定できます。例えば:

--[params]
--string :action_type = like

「クエリ期間 CTE」プロンプトを作成したのは、ChatGPT にクエリ期間 CTE の作成方法を具体的に指示しなかった場合、種々のソリューション(良いものも悪いものも)を提示してくるためです。プロンプトを使用すると、私が指定した正確なコードを追加し、その後問題なくその上にクエリを構築します。興味深いことに、ChatGPT に送信した初期ドキュメントに「クエリ期間 CTE」の作成方法に関する詳細を追加しようとした際、ChatGPT はその指示を無視しました。なぜか、別々のプロンプトとして送信すると違いが生まれます。

Discourse がトピックや投稿を「論理的に削除(soft delete)」する方法を説明するプロンプトも役立ちます。トピックや投稿に関連するクエリでは deleted_at IS NOT NULL をチェックする必要があることを ChatGPT に知らせた後、一貫してすべてのクエリにそれを適用しています。

ChatGPT にクエリの末尾からセミコロンを省略するように指示するのは、ほぼ不可能です。数回クエリでは覚えていますが、その後すぐにセミコロンを追加するよう戻ります。これは些細な詳細のようです。

自然言語の質問から完璧なクエリが返ってくるという私の当初の期待は、少し野心的でした。ChatGPT も私もミスをするものです。少なくとも短期的には、ChatGPT を Data Explorer プラグインと統合する最善の方法は、ChatGPT との PM(プライベートメッセージ)を開始することだと思われます。PM が作成された際にデータベースの基本的な説明を送信できます。その後、UI を介してプロンプトの選択を可能にします。例えば、クエリのパラメータ化用のプロンプトや、 rarely used table(あまり使用されないテーブル)に関する詳細を追加するためのプロンプトなどです。

これは、SQL に少し詳しい人にとって非常に役立つ可能性があると思われますが、SQL に慣れていない人でも、自力で学ぶよりもはるかに早く習得できるように実装することも可能かもしれません。今日、この素晴らしいトリックを学びました:

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
「いいね!」 4

あなたの依存症を助長していないことを願っています。

研究論文を読むかどうかはわかりませんが、今日、あなたが正しい道を歩んでおり、自然言語クエリから始めて有効な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

「いいね!」 1

@simon

もう一つ、あなたのお役に立つかもしれないアイデアがあります。これは少々突飛に聞こえるかもしれませんが、私はPrologコード、特にWebページを生成するためにこれを使用しました。

問題は、生成AIがSQLを理解するのが難しいことにあるのかもしれません。SQLは宣言型言語であり、生成AIがプログラミング言語で成功を収めているのは、JavaScript、Python、Javaなどの少数の命令型言語に関する大規模なトレーニングセットに基づいているからです。しかし、トランスフォーマーに基づいており、トランスフォーマーはもともと英語からドイツ語への翻訳のために開発されたと記憶していますが、よくトレーニングされたプログラミング言語との間で翻訳するのに優れています。したがって、最初にSQLを要求する代わりに、Pythonなどのよくトレーニングされたプログラミング言語に問題を解決するコードを要求し、次に生成AIにPythonをSQLに翻訳させて、それが機能するかどうかを確認してください。私はこれを試すつもりはありませんが、あなたがこれを楽しむようなので、どうぞお試しください。また、もしこれを試すなら、ぜひフィードバックをお願いします。発見したことをぜひ知りたいです。 :slightly_smiling_face:

「いいね!」 1

それはタイプミスですか?

WHERE poll_id = 74WHERE poll_id = 71 になるべきですか?


プロンプト全体を確認しませんでしたが、クエリの結果がどのようになるかの例が含まれているかどうかを確認していました。言い換えれば、テーブルの値の例は示されましたが、プロンプトの期待される結果の例は見られませんでした。おそらく見落としたのでしょう。期待される結果は、SQLが正しいかどうかを検証するために使用できます。


提案:

Discourse database prompt の例では、IDに 1 を使用することが複数のテーブルで使用されています。人間は 1 がフィールドとテーブルのコンテキストでのみ意味を持つことを理解しますが、AIはこれを理解しないため、AIが選択する機会を与える可能性があります。したがって、提案として Discourse database prompt を変更して、各IDに異なる数値を使用してください。

さらに一歩進んで、OpenAI Tokenizerページを使用して、各例テーブルのすべての値が単一のトークンであることを確認してください。それらのいくつかを単語、あるいはそれ以上に悪い文字列のままにしておきたいかもしれませんが、AIは本当にそれを気にしますか?複数のトークンを持つ値は、より多くのバリエーションと可能性のある幻覚につながるのでしょうか?

「いいね!」 1

間違いです。修正します。関連する他の投票テーブルの結果を取得するために、71 でクエリを再実行したと思います。

ブログ記事で推奨されている、すべての SELECT クエリを実行する方法から逸脱しました。
SELECT * FROM polls LIMIT 3;
これは、開発データベースに匿名ユーザーと削除された投稿がたくさんあるためです。その方がより一貫性のある結果が得られると考えましたが、新しいデータベースでプロンプトを再実行し、SELECT ステートメントを単純化してみます。

はい、すべての例で 3 人のユーザーを使用しています。ID は 12121 なので、これらの値は頻繁に繰り返されます。一貫性のあるデータを示すのが最善だと想定していました。いくつかの異なるアプローチを試して、何が最も効果的かを確認します。

ブログ記事で提案されているもう 1 つのアプローチは、プロンプトで設定する列を制限することです。それは魅力的ですが、多くのエラーを導入するリスクがあり、維持が困難になります。

私が 見ていると思う パターンは、複雑なクエリを要求してセッションを開始すると、ChatGPT が混乱することです。混乱を乗り越えさせると、セッションの残りの部分で結果は非常に良好になります。もう 1 つうまくいくと思われるアプローチは、単純なクエリから始めて、そこからより複雑なクエリに進むことです。それが実際のパターンなのか、それとも成功率が実際よりもランダムなのかはわかりません。

現状では、SQL と Discourse データベースに既に精通している人にとっては役立つようです。どちらについてもあまり知らない人にとって役立つレベルに到達させたいと思います。

ChatGPT-4 でもテストしています。おそらくより良い結果が得られるでしょうが、使用するのが less fun になるかもしれません。ChatGPT-3.5 ははるかに高速です。

「いいね!」 2

数十年前にデータベースを学んだとき、SQLを学ぶだけでも混乱しましたが、その後、Microsoft Accessのクエリビルダーを使いました。それはテーブルをドラッグ&ドロップし、Visioのように線でテーブルフィールド同士を接続するもので、SQLを生成してくれました。

同様のツール、こちらからの画像

DiscourseがSQL構築のためのそのようなツールを作成するとは期待しませんが、接続されたテーブルのそのような画像をフィードバックとして生成するためにAIを利用することは可能かもしれません。


このビデオで言及されているように、まずGPT-4で正しい結果を作成し、次に速度のためにGPT-3.5でカスタマイズします。

「いいね!」 2