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
8 Likes

Trying to find the correct query to be able to search all users which have a custom user field Pro Email, but to find the users which are not in the Pro group?

I moved your post to this topic. I think the last query in my previous post in this topic will get you close to what you are looking for. If your custom field is a confirmation type, enter ‘true’ for the field_value parameter. That will return all users who have checked the confirmation box for the field name you supply for the query’s field_name parameter.

The query will need to be added to so that you can filter out users who are already in your Pro group.

2 Likes

Any example for a query on how to filter out users already in that group and then only return users not in that group?

I have not used the data explorer plugin for Discourse that much.

Here’s one way to do it. It adds an excluded_users temporary table that’s made up of members of the excluded group. You will need to supply the group’s Name for the query’s group_name parameter.

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

Thank you for that data explorer query, much appreciated.

What would need to defined in the field_value since I just need to have to process if it has a value set for the Pro Email user custom field?

If Pro Email is a confirmation field (checkbox) then setting the query’s field_value parameter to true will work.

SInce all you are wanting to do is check that the field has been set, I think this version of the query will work better for you. It removes the field_value parameter and checks that the named field has been set with (ucf.value = '') IS NOT TRUE. This will return false for any users who have not set the field, and will also return false for users who have set the field and then deleted the value they set:

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

If you’d like the query to return the field’s value, change the final select statement to:

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)
3 Likes

Thank you it works great!

Hi @simon , which one of these queries would work if I had multiple custom fields and just wanted to return a list of users and their answers to those custom fields? I’ve got questions like “where did you hear about us” which has a checkboxes to allow for multiple choices, and another that asks how they would like to be contacted email, SMS and post.
Thanks
Clement

None of the above queries will give you exactly what you are looking for. Without writing a new query, the best approach would be to run the first query I posted multiple times. Run it one time for each of your custom fields. Enter the field’s name into the query’s field_name input. The query I’m referring to is this one:

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