Вы объединяете два источника событий через UNION ALL: в одном user_id имеет тип int, в другом user_id_text имеет тип text (значения выглядят как 42 и могут содержать пробелы). Дальше вы делаете JOIN к users.id (тип int). Что надежнее сделать, чтобы избежать ошибок типов и неожиданных сравнений?

AНичего не делать: типы в UNION ALL всегда сохраняются «как есть».
BПривести users.id к text в финальном JOIN: users.id::text = events.user_id.
CСделать LOWER(user_id_text) перед UNION ALL, чтобы тип стал совместимым.
DЯвно привести тип в обоих селектах до объединения, например SELECT user_id AS user_id ... UNION ALL SELECT CAST(TRIM(user_id_text) AS int) AS user_id ....
Правильный ответ. В объединениях и последующих JOIN лучше заранее привести ключи к одному типу явным образом.

Разбор

Когда источники имеют разные типы, неявные приведения могут приводить к ошибкам, неожиданным результатам или лишним преобразованиям на каждом шаге. Приведение ключа к int до UNION ALL делает тип итоговой колонки контролируемым и понятным, а TRIM помогает убрать простой «мусор» вроде пробелов. Это снижает риск багов в дальнейших соединениях и фильтрах.

Проверь себя · 1/3разбор после ответа
В таблице events поле event_date_text хранит дату как текст в формате YYYY-MM-DD. Вы хотите считать метрики по неделям и использовать функции дат. Что логичнее сделать в запросе?
Тренировать SQL в Telegram

Ещё вопросы по теме «Строки и приведение типов»