¿Puedes compartir algunos ejemplos de casos extremos?
Claro, planeo hacer otra ronda la próxima semana, puedes probar el script de ruby en el repositorio que compartí.
@simon Creo que el valor real es comprender que, al menos en el futuro previsible, esto nunca saldrá bien a la primera. Pero si sabes lo que quieres, puedes guiarlo como un becario implacable que puede hacer el trabajo pesado.
Así que, sin tener ningún conocimiento actual de SQL más allá de recordar select from where, y sabiendo cuál quería que fuera mi resultado final, logré que construyera la consulta que quería simplemente conversando con ella, y sin que me quitara tiempo de mi trabajo diario. Realmente es como tener un asistente personal/becario gratuito al que solo necesito seguir guiando en la dirección correcta.
En primer lugar, aquí está mi consulta final. Quería una consulta que devolviera los 100 usuarios principales con más “me gusta” totales, y que me diera su usuario, nombre de usuario, recuento de “me gusta” totales y un enlace a su única publicación que tuviera la mayor cantidad de “me gusta”. No sabía/no sé cómo conseguir esto en absoluto, y francamente, ni siquiera sé por dónde empezar. Cuando quiero algo así, molesto a uno de mis ingenieros. Pude no molestarlos, no ralentizar mi propio trabajo realmente, y aun así guiar/instruir a ChatGPT para que hiciera lo que necesitaba.
Consulta final:
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
Instrucciones en mi cuenta de ChatGPT antes de comenzar el prompt:
Solo te haré preguntas relacionadas con PostgreSQL, y solo quiero que respondas con consultas SQL relevantes.
Estas consultas están relacionadas con las bases de datos de mi plataforma comunitaria, Discourse.
Responde con consultas SQL y explicaciones de las consultas. No uses punto y coma para finalizar las sentencias SQL, ya que no son necesarios.
Sigue toda mi conversación en ChatGPT construyendo esta consulta aquí:
@sam con un esquema completo como el anterior (de nuevo, lo siento, no sé dónde conseguir esto y/o conseguirlo en este formato) y usando langchain y una base de datos vectorial para procesar los documentos correctamente antes de enviarlos a ChatGPT, además de cualquier documento que tengas sobre el uso del Explorador de Datos… estoy bastante seguro de que este proceso sería casi mágico.
Probé una base de datos vectorial y le proporcioné ejemplos similares, la dirige demasiado, probablemente necesitaremos 1000 ejemplos muy cercanos para que sea mágica.
Mi ingeniero también lo intentará, ya que hemos creado una especie de “fábrica” para producirlos con bastante rapidez.
¿Hay algún lugar donde pueda obtener un documento completo y exhaustivo de todos los esquemas de base de datos en este formato?
# == 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
Ese formato consume demasiados tokens, pero puedes consultarlo directamente de las tablas del esquema pg en el explorador de datos ![]()
Jaja, está bien, haré que lo revise. Como dije, no soy yo quien va a ir más allá con esto. Si lo fuera, ¡probablemente no estaría haciendo estas preguntas!
Realmente quiero que algo funcione, pero este es un problema muy difícil.
Esta es solo una idea, no la he probado.
Las consultas necesarias en mi opinión se desglosan en usos basados en el deber
- moderador
- administrador
- desarrollador
Como tal, las tablas necesarias se pueden agrupar en conjuntos en constante crecimiento, siendo el conjunto más pequeño las tablas necesarias para un moderador.
Ahora, muchos de los datos necesarios para un moderador se basarán en uniones comunes de tablas con columnas específicas, por lo tanto, una vista.
Si se utilizan las vistas comunes en lugar del esquema completo, entonces, con suerte, muchas de las indicaciones solo necesitarán pasar las vistas y no el esquema completo, lo que facilitará mucho que el LLM genere una posible solución.
Espero que sirva
Para las consultas mucho más difíciles, lo más probable es que si sabes lo suficiente para necesitar una consulta de este tipo, sepas lo suficiente para construir la consulta.
Lo he intentado. Los resultados están por todas partes. Un experimento interesante es proporcionar a GPT-3.5 una versión anotada mínima del esquema de la base de datos de Discourse solo para probar su capacidad SQL. Me doy cuenta de que esto es ineficiente en términos de tokens, pero es legible:
Esquema mínimo
# == Información del esquema
#
# Nombre de la tabla: users
#
# id :integer not null, primary key
# username :string(60) not null
# created_at :datetime not null
#
# Nombre de la tabla: groups
#
# id :integer not null, primary key
# name :string not null
# created_at :datetime not null
#
# Nombre de la tabla: group_users
#
# id :integer not null, primary key
# group_id :integer not null
# user_id :integer not null
#
# Nombre de la tabla: posts
#
# id :integer not null, primary key
# user_id :integer
# topic_id :integer not null
# deleted_at :datetime (La aplicación "elimina suavemente" las publicaciones. Cuando se elimina una publicación, su propiedad `deleted_at` se establece en un :datetime. A menos que se solicite explícitamente la devolución de publicaciones eliminadas, asegúrese de que la columna `deleted_at` sea `NOT NULL` al escribir consultas que soliciten datos relacionados con las publicaciones.)
#
# Nombre de la tabla: topics
#
# id :integer not null, primary key
# title :string not null
# category_id :integer
# created_at :datetime not null
# user_id :integer (el id del usuario que creó el tema)
# deleted_at :datetime (La aplicación "elimina suavemente" los temas. Cuando se elimina un tema, su propiedad `deleted_at` se establece en un :datetime. A menos que se solicite explícitamente la devolución de temas eliminados, asegúrese de que la columna `deleted_at` sea `NOT NULL` al escribir consultas que soliciten datos relacionados con los temas.)
#
# Nombre de la tabla: categories
#
# id :integer not null, primary key
# name :string(50) not null
Hasta ahora, los resultados que estoy obteniendo son impresionantes. Esto me hace pensar que el problema podría resolverse simplemente proporcionando un esquema anotado en el prompt.
Para divertirme, le pregunté qué tipo de consultas podría esperar que le resultaran difíciles:
Limitaciones de GPT-3.5
- Consultas Jerárquicas: Las consultas que involucran estructuras de datos jerárquicas, como relaciones recursivas, pueden ser complejas. Por ejemplo, consultar relaciones padre-hijo dentro de una jerarquía de categorías.
- Consultas Temporales: Las consultas que involucran datos basados en el tiempo, como el cálculo de tendencias históricas o el análisis de datos durante intervalos de tiempo específicos, pueden requerir construcciones SQL más intrincadas.
- Funciones de Ventana: Si bien he utilizado funciones de ventana en consultas anteriores, los usos más avanzados de funciones de ventana para tareas analíticas complejas pueden ser desafiantes.
- Consultas Geoespaciales: Las bases de datos espaciales y las consultas basadas en datos geográficos, como la búsqueda de ubicaciones cercanas o relaciones espaciales complejas, pueden ser complejas.
- Agregaciones Complejas: Las agregaciones avanzadas que involucran múltiples niveles de agrupación y cálculos pueden requerir un conocimiento SQL más intrincado.
- Consultas de Optimización: Escribir consultas altamente optimizadas que involucren índices, ajuste de consultas y mejoras de rendimiento puede ser intrincado.
- Algoritmos Personalizados: La implementación de algoritmos o lógica personalizados dentro de una consulta SQL puede ser desafiante debido a la complejidad de la lógica involucrada.
- JOINs Avanzados: Las condiciones de unión complejas o la combinación de múltiples uniones pueden requerir una cuidadosa consideración y posiblemente construcciones SQL más complejas.
- Subconsultas y Subconsultas Correlacionadas: Si bien puedo manejar subconsultas, las subconsultas extremadamente complejas o anidadas profundamente pueden ser más desafiantes.
- Pivoteo y Despivoteo: Transformar datos entre formatos anchos y altos (pivoteo y despivoteo) puede volverse complejo en ciertos escenarios.
Donde encuentro problemas es al intentar desambiguar el esquema completo de la base de datos. Por ejemplo, encontrar una forma de anotar la tabla user_actions. Simplemente proporcionar definiciones de sus códigos de action_type no es suficiente. Empieza a adivinar sobre user_id, target_user_id y acting_user_id.
Las consultas que se solicitan con más frecuencia no utilizan la mayoría de las tablas y columnas de la base de datos. Si se añade IA al Explorador de Datos, podría valer la pena considerar tener modos “básico” y “avanzado”. El modo básico podría proporcionar un prompt que cubra la mayoría de los casos de uso. El modo avanzado permitiría a los usuarios seleccionar qué información se establece en el prompt.
Sería interesante trabajar hacia atrás a partir de algunas solicitudes de consultas sobre metadatos, para ver qué se necesitaría proporcionar al prompt para que GPT-3.5 cree la consulta con éxito.
Potencialmente un enfoque de langchain donde primero le pedimos a gpt que determine qué tablas son relevantes, seguido de una segunda fase donde generamos el sql puede ayudar.
Nuestra propia implementación para nuestro producto utiliza actualmente langchain. De hecho, hemos creado una especie de fábrica reutilizable, voy a hacer que mi ingeniero principal pruebe esto pronto.
Como dije, sin embargo, estoy bastante contento con los resultados hasta ahora. Es como tener un asistente que hace recados por mí, solo necesita hacer algunos viajes, pero aun así me ahorra mucho tiempo y dinero tal como está ahora.
Para tu información
Esto es súper adictivo. Basado en el artículo del blog “LLMs y SQL”, y un poco de prueba y error, creé este prompt que contiene una descripción parcial de la base de datos de Discourse:
Prompt de la base de datos de Discourse
El texto entre los comentarios /* Discourse database documentation start */ y /* Discourse database documentation end */ contiene detalles sobre la base de datos PostgreSQL de la aplicación de foro Discourse.
Todas las tablas y columnas se describen en las sentencias `CREATE TABLE`. Presta atención a las consultas de ejemplo que siguen a cada una de las sentencias `CREATE TABLE`. Algunos detalles importantes adicionales se encuentran en
comentarios en línea (`-- --`) y multilínea (`/* */`). Después de enviarte esta información, te pediré que escribas algunas consultas que deben ejecutarse mediante el plugin Discourse Data Explorer. Todas las tablas y columnas
necesarias para escribir estas consultas están en las sentencias `CREATE TABLE` que te he enviado.
/* Discourse database documentation start */
CREATE TABLE users (
id integer NOT NULL, -- la aplicación tiene el concepto de usuarios 'reales'. Un usuario 'real' es un usuario con un 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
); -- los usuarios que tienen estado 'admin' o 'moderator' se agregan al grupo automático "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 une las tablas groups y 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, -- la aplicación solo "elimina suavemente" (soft deletes) posts y topics. A menos que se solicite explícitamente devolver detalles sobre posts o topics eliminados, verifica siempre que `deleted_at IS NULL` al escribir consultas relacionadas con posts o 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, -- id de usuario, el id del usuario que creó el tema --
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, -- la aplicación solo "elimina suavemente" (soft delete) publicaciones y temas. A menos que se solicite explícitamente devolver detalles sobre publicaciones o temas eliminados, verifica siempre que `deleted_at IS NULL` al escribir consultas relacionadas con publicaciones o temas. --
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 puede establecerse en 'regular' o '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 (cuando un usuario da me gusta a una publicación), :was_liked=>2 (cuando la publicación de un usuario recibe me gusta), :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;
/*
En el primer ejemplo a continuación, el usuario con el id 1 ha dado me gusta (action_type: 1) a la publicación con el id 11100. Como el usuario con el id 1 realizó la acción, 1 se establece como el valor de la columna acting_user_id. Como la entrada registra que este usuario ha realizado una acción de "me gusta", su id de usuario (1) también se establece en la columna user_id de la entrada.
Aquí hay una consulta de ejemplo que devolvería el número de veces que el usuario con id: 1 ha dado me gusta a publicaciones de otros usuarios: `SELECT COUNT(user_id) AS number_of_likes_given FROM user_actions WHERE action_type = 1 AND user_id = 1;`
En el segundo ejemplo a continuación, el usuario con el id 121 ha recibido me gusta en su publicación (id 11100) por parte de otro usuario (action_type: 2). La columna user_id de la entrada se establece en 121 porque ese es el id del usuario que ha recibido me gusta en su publicación. La columna acting_user_id de la entrada se establece en 1 porque ese es el usuario que dio me gusta a la publicación.
Aquí hay una consulta de ejemplo que devuelve el número de veces que el usuario con id 121 ha recibido me gusta en sus publicaciones por parte de otros usuarios: `SELECT COUNT(user_id) AS number_of_likes_received FROM user_actions WHERE action_type = 2 AND user_id = 121;`
Aquí hay una consulta de ejemplo que devuelve el número de veces que el usuario con id 121 ha recibido me gusta en sus publicaciones por parte del usuario con 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;`
En el tercer ejemplo, el usuario con el id 121 ha sido mencionado (action_type: 7) en la publicación (id 11101) por el usuario con el id 2. La columna user_id de la entrada se establece en 121 porque ese es el id del usuario que fue mencionado. La columna acting_user_id de la entrada se establece en 2 porque ese es el id del usuario que creó la mención.
Aquí hay un ejemplo que devuelve el número de veces que el usuario con id 121 ha sido mencionado por cualquier usuario: `SELECT COUNT(user_id) AS number_of_mentions_received FROM user_actions WHERE action_type = 7 AND user_id = 121;`
Aquí hay una consulta de ejemplo que devuelve el número de veces que el usuario con id 121 ha sido mencionado por el usuario con 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;`
Aquí hay una consulta de ejemplo que devuelve el número de veces que el usuario con id 121 ha sido mencionado en el tema con el 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
/* Fin de la documentación de la base de datos de Discourse */
Cubre las tablas users, groups, group_users, posts, topics, categories, tags, topic_tags, user_actions, polls, poll_options y poll_votes. Actualmente tiene 1150 tokens, por lo que debería poder duplicar su tamaño sin causar problemas. Ten en cuenta que si lo copias en un cuadro de entrada de chat de ChatGPT, necesitarás pegarlo en dos cuadros de entrada separados: el límite de caracteres de un cuadro de entrada de chat es menor que el límite de tokens para una sesión de chat.
Añadí comentarios bastante detallados antes de las consultas de ejemplo de user_actions. Con esos ejemplos, ChatGPT está haciendo un buen trabajo al responder preguntas sobre me gusta dados, me gusta recibidos, etc. Anteriormente había tenido dificultades con eso. Sospecho que hay algunas tablas que necesitarían un enfoque similar.
Después de enviar la documentación, los siguientes prompts son útiles:
Ejemplos de prompts
Cuando te pida que inicies una consulta con un ‘CTE de período de consulta’, quiero que la consulta comience exactamente con este SQL (incluyendo el comentario):
--[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
)
El complemento Data Explorer permite agregar parámetros a sus consultas. Los parámetros que se utilizan en las consultas deben aparecer en un comentario en la parte superior de la consulta en este formato:
--[params]
--param_type :param_name
Los tipos de parámetros disponibles son:
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
Aquí hay un ejemplo:
--[params]
-- string :action_type
Se puede proporcionar un valor predeterminado opcional para un parámetro. Por ejemplo:
--[params]
--string :action_type = like
Creé el prompt “CTE de período de consulta” porque si no le indicaba específicamente a ChatGPT cómo crear el CTE de período de consulta, proponía todo tipo de soluciones, algunas mejores que otras. Con el prompt, añade el código exacto que le doy, luego construye consultas sobre él sin ningún problema. Curiosamente, cuando intenté añadir detalles sobre cómo crear un “CTE de período de consulta” a la documentación inicial que envié a ChatGPT, simplemente ignoraba las instrucciones. Por alguna razón, enviarlo como un prompt separado hace la diferencia.
Los prompts que describen cómo Discourse “elimina suavemente” (soft delete) temas y publicaciones también son útiles. Después de informarle a ChatGPT sobre la necesidad de verificar que deleted_at IS NOT NULL para consultas relacionadas con temas y publicaciones, aplica consistentemente esto a todas las consultas.
Pedirle a ChatGPT que omita el punto y coma al final de las consultas es algo desesperado. Lo recuerda durante un par de consultas, luego vuelve a añadir el punto y coma. Eso parece un detalle menor.
Mi esperanza inicial de obtener una consulta perfecta a partir de una pregunta en lenguaje natural era un poco ambiciosa. Comete errores, y yo también. Al menos a corto plazo, creo que la mejor manera de integrar ChatGPT con el complemento Data Explorer sería iniciar un mensaje privado con ChatGPT. Se podría enviar una descripción básica de la base de datos cuando se cree el mensaje privado. Luego, una selección de prompts podría estar disponible a través de la interfaz de usuario. Por ejemplo, un prompt para parametrizar una consulta, o un prompt para añadir detalles sobre una tabla poco utilizada.
Mi sospecha es que esto podría ser muy útil para alguien que conozca un poco de SQL, pero posiblemente también podría implementarse de una manera que ayudara a las personas que son nuevas en SQL a ponerse al día mucho más rápido de lo que lo harían por su cuenta. Aprendí este maravilloso truco hoy:
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
Espero no estar alimentando tu adicción.
No sé si lees artículos de investigación, pero hoy me encontré con otro que refuerza que estás en un camino válido y que el artículo puede señalar nuevas vías para lograr el objetivo de generar SQL y resultados válidos a partir de una consulta en lenguaje natural.
El artículo es para problemas matemáticos, pero dado que las matemáticas son solo una expresión al igual que el SQL, solo cambia una forma de expresión por otra y debería tener sentido. Hay muchos artículos relacionados con ideas similares, así que no consideres este como autoritario.
“Solving Challenging Math Word Problems Using Gpt-4 Code Interpreter With Code-Based Self-Verification” de Aojun Zhoun, Ke Wang, Zimu Lu, Weikang Shi, Sichun Luo, Zipeng Qin, Shaoqing Lu, Anya Jia, Linqi Song, Mingjie Zhan y Hongsheng Li (pdf)
Otra idea que podría ayudarte y esta puede parecer que estoy bajo los efectos de los hongos, pero la he usado para generar código Prolog, específicamente páginas web.
El problema puede ser que la IA generativa tiene más dificultades para entender SQL porque es un lenguaje declarativo y gran parte del éxito con los lenguajes de programación con IA generativa proviene de grandes conjuntos de datos de entrenamiento en algunos lenguajes de programación imperativos como JavaScript, Python, Java, etc. Pero la IA generativa, que se basa en transformadores, y los transformadores se crearon inicialmente para traducir del inglés al alemán, si no me equivoco, son excelentes para traducir desde/hacia los lenguajes de programación bien entrenados. Por lo tanto, en lugar de pedir SQL al principio, pide un Python u otro lenguaje de programación bien entrenado para que el código resuelva el problema, luego haz que la IA generativa traduzca el Python a SQL y ve si eso funciona. No planeo intentarlo, pero ya que parece que disfrutas de esto, adelante. Además, si haces esto, por favor, da tu opinión, ya que definitivamente me gustaría saber qué descubres. ![]()
¿Es eso un error tipográfico?
¿Debería WHERE poll_id = 74 ser WHERE poll_id = 71?
No revisé todo el aviso, solo estaba buscando ver si incluiste un ejemplo de cómo deberían verse los resultados de la consulta. En otras palabras, diste ejemplos de los valores de la tabla, pero no vi un ejemplo del resultado esperado para un aviso, tal vez me lo perdí. El resultado esperado podría usarse para validar si el SQL es correcto.
Sugerencia:
En el ejemplo Aviso de base de datos de Discourse, el uso de 1 para el id se utiliza en varias tablas. Mientras que los humanos entendemos que el 1 solo tiene significado con el contexto del campo y la tabla, la IA no lo sabrá y eso podría darle a la IA la oportunidad de tomar una decisión. Por lo tanto, como sugerencia, modifica el Aviso de base de datos de Discourse para usar números diferentes para cada id.
Para ir un paso más allá, verifica que todos los valores en cada tabla de ejemplo sean un solo token utilizando la Página de Tokenizador de OpenAI. Sé que tal vez quieras mantener algunos como palabras o, peor aún, cadenas, pero ¿realmente le importa a la IA? ¿Los valores de múltiples tokens conducirán a más variación y posibles alucinaciones?
Es un error. Lo arreglaré. Creo que volví a ejecutar la consulta con 71 para intentar incluir resultados que fueran relevantes para las otras tablas relacionadas con las encuestas.
Me desvié de la sugerencia de la entrada del blog de ejecutar todas las consultas SELECT con este formato:
SELECT * FROM polls LIMIT 3;
Lo hice porque tengo muchos usuarios anonimizados y publicaciones eliminadas en mi base de datos de desarrollo. Pensé que así proporcionaría resultados más coherentes, pero intentaré rehacer la indicación con una base de datos nueva y simplificaré las declaraciones SELECT.
Sí, estoy usando tres usuarios en todos los ejemplos. Sus IDs son 1, 2 y 121, por lo que esos valores se repiten mucho. Suponía que sería mejor mostrar datos coherentes. Probaré algunos enfoques diferentes y veré cuál funciona mejor.
Otro enfoque que se sugiere en la entrada del blog es limitar las columnas que se establecen en la indicación. Eso es tentador, pero corre el riesgo de introducir muchos errores, sería difícil de mantener, etc.
El patrón que creo que estoy viendo es que si comienzo una sesión pidiendo una consulta compleja, ChatGPT se confunde. Logro que supere su confusión y luego los resultados son bastante buenos durante el resto de la sesión. El otro enfoque que parece funcionar es comenzar con una consulta simple y pasar a consultas más complejas a partir de ahí. No estoy seguro de si es un patrón real o si la tasa de éxito es en realidad más aleatoria de lo que parece.
Tal como está ahora, parece que sería útil para alguien que ya está familiarizado con SQL y la base de datos de Discourse. Me gustaría que llegara al punto en que fuera útil para alguien que no supiera mucho sobre ninguna de las dos.
También estoy probando esto con ChatGPT-4. Parece probable que produzca mejores resultados, pero tal vez sea menos divertido de usar. ChatGPT-3.5 es mucho más rápido.
Hace décadas, cuando aprendí bases de datos, era confuso solo aprender del SQL, pero luego usé el generador de consultas de Microsoft Access, que consistía en arrastrar y soltar tablas y luego conectar los campos de las tablas entre sí con líneas, muy parecido a como funciona Visio, y eso generaba el SQL.
Herramienta similar, imagen de aquí
No esperaría que Discourse creara una herramienta así para construir un SQL, pero podría ser posible que la IA generara tales imágenes de las tablas conectadas como retroalimentación.
Si mal no recuerdo, en este video se señala que primero se cree con GPT-4 para obtener los resultados correctos, y luego se personalice para GPT-3.5 por velocidad.
