Query to filter users by sign-up 'custom fields'

I have a custom dropdown field setup on sign up where users select a ‘Category’ that best suits them.

How can I find users based on what they selected within that dropdown?

To get all values for a named field, try this, with the name of your field entered into the field_name input:

--[params]
-- string :field_name

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
)

SELECT
u.id AS user_id,
ucf.value
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)

To get the value of a user field for a specific user:

--[params]
-- string :field_name
-- string :username

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
)

SELECT
u.id AS user_id,
ucf.value
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)
AND u.username = :username

To only get users who have entered a specific value for a field, try this, with the name of the field entered into the field_name input, and the value you are looking for entered into the field_value input:

--[params]
-- string :field_name
-- string :field_value

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
)

SELECT
u.id AS user_id
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)
AND ucf.value = :field_value

Пытаюсь найти правильный запрос для поиска всех пользователей, у которых есть пользовательское поле «Pro Email», но которые не входят в группу «Pro»?

Я переместил ваш пост в эту тему. Я думаю, что последний запрос в моём предыдущем сообщении в этой теме приблизит вас к желаемому результату. Если ваше пользовательское поле является полем подтверждения, укажите «true» для параметра field_value. Это вернёт всех пользователей, которые отметили поле подтверждения для имени поля, указанного вами в параметре field_name запроса.

Запрос необходимо дополнить, чтобы вы могли исключить пользователей, которые уже находятся в вашей группе Pro.

Можете привести пример запроса, который позволяет отфильтровать пользователей, уже состоящих в этой группе, и вернуть только тех, кто в ней не состоит?

Я не очень часто использую плагин Data Explorer для Discourse.

Вот один из способов это сделать. Он создаёт временную таблицу excluded_users, состоящую из участников исключённой группы. Для параметра group_name в запросе вам нужно указать имя группы.

--[params]
-- string :field_name
-- string :field_value
-- string :group_name

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
),
excluded_users AS (
SELECT
gu.user_id
FROM group_users gu
JOIN groups g
ON g.id = gu.group_id
WHERE g.name = :group_name
)

SELECT
u.id AS user_id
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)
AND ucf.value = :field_value
AND u.id NOT IN (SELECT user_id FROM excluded_users)

Спасибо за этот запрос Data Explorer, очень ценю.

Что нужно определить в field_value, если мне нужно обрабатывать только тот случай, когда для пользовательского поля «Pro Email» установлено значение?

Если «Pro Email» — это поле подтверждения (флажок), то установка параметра field_value запроса в true сработает.

Поскольку ваша цель — просто проверить, установлено ли поле, эта версия запроса, вероятно, подойдёт вам лучше. Она убирает параметр field_value и проверяет, что именованное поле установлено, используя условие (ucf.value = '') IS NOT TRUE. Это вернёт false для любых пользователей, не установивших поле, а также для тех, кто установил поле, но затем удалил заданное значение:

--[params]
-- string :field_name
-- string :group_name

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
),
excluded_users AS (
SELECT
gu.user_id
FROM group_users gu
JOIN groups g
ON g.id = gu.group_id
WHERE g.name = :group_name
)

SELECT
u.id AS user_id
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)
AND (ucf.value = '') IS NOT TRUE
AND u.id NOT IN (SELECT user_id FROM excluded_users)

Если вы хотите, чтобы запрос возвращал значение поля, измените финальный оператор SELECT следующим образом:

SELECT
u.id AS user_id,
ucf.value
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)
AND (ucf.value = '') IS NOT TRUE
AND u.id NOT IN (SELECT user_id FROM excluded_users)

Спасибо, всё отлично работает!

Привет, @simon, какой из этих запросов сработает, если у меня несколько пользовательских полей и я хочу получить список пользователей и их ответы на эти поля? У меня есть вопросы вроде «Откуда вы о нас узнали?», где есть чекбоксы для выбора нескольких вариантов, и другой вопрос о том, как они хотели бы получать контакты: по электронной почте, SMS или по почте.
Спасибо,
Клеман

Ни один из вышеуказанных запросов не даст вам именно то, что вы ищете. Без написания нового запроса лучшим подходом будет многократный запуск первого запроса, который я опубликовал. Запустите его один раз для каждого из ваших пользовательских полей. Введите имя поля в входное поле field_name запроса. Запрос, на который я ссылаюсь, выглядит так:

--[params]
-- string :field_name

WITH ucf_name AS(
SELECT
CONCAT('user_field_', id) AS name
FROM user_fields
WHERE name = :field_name
)

SELECT
u.id AS user_id,
ucf.value
FROM users u
JOIN user_custom_fields ucf
ON ucf.user_id = u.id
WHERE ucf.name = (SELECT name FROM ucf_name)