Фильтровать лайки пользователей, если аккаунт был создан за x дней до создания темы

Привет,

Я пытаюсь добавить ещё один фильтр: если пользователь был создан менее чем за 2 дня до создания определённой темы, он не должен включаться в результат.

Вот что я попробовал. Я относительно новичок в SQL, поэтому не уверен, как правильно это сделать. Любая помощь будет полезна!

SELECT *
FROM topic t
INNER JOIN post_actions pa ON t.id = pa.topic_id
INNER JOIN users u ON u.id = pa.user_id
WHERE post_id = 1
    AND post_action_type_id = 2
    AND u.created_at < t.created_at - INTERVAL '2 days'

Не совсем понимаю, к чему вы клоните в данном случае? Не могли бы вы уточнить, чего именно вы хотите добиться?

Я пытаюсь исправить фильтр по дате, чтобы исключить пользователей, созданных менее чем за 2 дня до появления определённой темы. Мне советовали использовать либо DATEDIFF, либо INTERVAL, но ни один из вариантов не сработал.

Также мне нужна была помощь с добавлением темы t ещё одним INNER JOIN, но я решил это так:
FROM post_actions pa INNER JOIN users u ON u.id = pa.user_id INNER JOIN topics t ON t.id = t.id

Поле t.id отображается как число, а не как превью. Есть ли способ это исправить?

В этом случае вам достаточно использовать псевдоним t.id AS topic_id, и всё заработает как по волшебству. :+1:

В этой теме есть ещё несколько примеров «магии» Explorer, которые вы можете использовать: IDs in Data Explorer - #3 by tshenry

Когда вы говорите «определённая тема», имеется в виду одна и та же тема каждый раз? (т.е. статический ID темы)

Да, одна и та же тема каждый раз.

Кажется, мне удалось заставить это работать с помощью этого запроса. Результатов было более 1000, поэтому я попробовал добавить
AND t.id = post.topic_id.

Это сократило список до 16 результатов, но всё ещё было 4 одинаковых записи. Не уверен, как это исправить.

SELECT
    t.id as topic_id,
    pa.post_id,
    pa.user_id,
    pa.created_at,
    u.created_at
FROM  post_actions pa INNER JOIN users u ON u.id = pa.user_id INNER JOIN topics t on t.id = t.id INNER JOIN posts p on p.topic_id = p.topic_id
WHERE post_id = 15000
    AND t.id = 7000
    AND post_action_type_id = 2
    AND u.created_at < t.created_at - INTERVAL '2 DAY'

РЕДАКТИРОВАНО: Изменил
INNER JOIN posts p on p.topic_id = p.topic_id
на
INNER JOIN posts p on p.topic_id = t.id,
что сократило количество до 16 результатов, как и раньше.

Теперь я думаю, что причина, по которой их всё ещё 16, в том, что у меня написано t.id = t.id. Не уверен, на что это можно изменить.

В этом есть несколько проблем, хотя я недостаточно уверенно владею SQL, чтобы полностью их объяснить. :slightly_smiling_face:

Думаю, вам не понадобится topic_id, если у вас уже есть post_id, так как идентификатор поста уникален для этого поста (и темы). Также вы, похоже, пытаетесь присоединить некоторые дополнительные таблицы по полям, которых нет во второй таблице (например, t.id = t.id — это одно и то же поле в таблице тем). И если тема, против которой вы выполняете запрос, статична, то вам не понадобится относительный INTERVAL, поскольку дата всегда будет одинаковой (то есть за 2 дня до создания поста 15000), поэтому её можно задать явно.

У меня пока не было возможности попробовать свой вариант, но я научился большинству навыков работы с SQL и бейджами, просматривая примеры на Meta и заимствуя фрагменты кода. :slight_smile: Многие из них помечены тегом data-explorer, а в статье Идеи для некоторых распространённых запросов на получение бейджей есть множество примеров для разных задач — возможно, стоит посмотреть?

Да, я знаю, но всякий раз, когда я убираю условие AND для topic_id, количество результатов почему-то снова возрастает до 1000. Я посмотрю ссылку, которую вы прислали. Надеюсь, мне удастся решить некоторые из этих проблем.

Я всё ещё не совсем понимаю, к чему вы клоните, но если вы знаете post_id и дату, с которой нужно включить новых пользователей, то, возможно, что-то вроде этого?

-- [params]
-- int :post_id
-- date :date


SELECT pa.user_id,
       pa.created_at AS reltime$time
FROM post_actions pa 
JOIN users u ON u.id = pa.user_id
WHERE pa.post_id = :post_id
AND post_action_type_id = 2
AND u.created_at::date > :date
ORDER BY pa.created_at DESC

Это вернёт список пользователей, которые лайкнули определённый пост и создали свой аккаунт после указанной вами даты (отсортированный по времени лайка).

Мне удалось всё настроить — я даже не знал о reltime, но теперь внедрил его в систему. Ещё раз спасибо за помощь!

Остался один вопрос, касающийся reltime. Можно ли изменить название с «time» на что-то вроде «Тема создана»?

Абсолютно верно. :slightly_smiling_face: Если вы измените это на reltime$topic_created, это должно сработать. :+1: