Consulta para filtrar usuários por 'campos personalizados' de cadastro

Tenho um campo de lista suspensa personalizado configurado no cadastro, onde os usuários selecionam uma “Categoria” que melhor os representa.

Como posso encontrar usuários com base no que eles selecionaram nessa lista suspensa?

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

Estou tentando encontrar a consulta correta para pesquisar todos os usuários que possuem um campo personalizado de usuário ‘Pro Email’, mas que não estão no grupo ‘Pro’?

Movi sua postagem para este tópico. Acredito que a última consulta em minha postagem anterior neste tópico o aproximará do que você está procurando. Se seu campo personalizado for do tipo confirmação, insira ‘true’ no parâmetro field_value. Isso retornará todos os usuários que marcaram a caixa de confirmação para o nome do campo que você fornecer no parâmetro field_name da consulta.

A consulta precisará ser modificada para que você possa filtrar os usuários que já estão no seu grupo Pro.

Alguém tem um exemplo de uma consulta que filtre os usuários que já estão naquele grupo e retorne apenas os que não estão?

Não tenho muita experiência com o plugin Data Explorer do Discourse.

Aqui está uma maneira de fazer isso. Ela adiciona uma tabela temporária excluded_users composta pelos membros do grupo excluído. Você precisará fornecer o Nome do grupo para o parâmetro group_name da consulta.

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

Obrigado por essa consulta do Data Explorer, muito apreciada.

O que precisaria ser definido no field_value, já que só preciso processar se houver um valor definido para o campo personalizado do usuário Pro Email?

Se o Pro Email for um campo de confirmação (caixa de seleção), definir o parâmetro field_value da consulta como true funcionará.

Como tudo o que você deseja é verificar se o campo foi definido, acredito que esta versão da consulta funcione melhor para você. Ela remove o parâmetro field_value e verifica se o campo nomeado foi definido com (ucf.value = '') IS NOT TRUE. Isso retornará false para qualquer usuário que não tenha definido o campo e também retornará false para usuários que definiram o campo e depois excluíram o valor definido:

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

Se você quiser que a consulta retorne o valor do campo, altere a instrução SELECT final para:

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)

Obrigado, funciona muito bem!

Olá @simon, qual destas consultas funcionaria se eu tivesse vários campos personalizados e quisesse apenas retornar uma lista de usuários e suas respostas a esses campos personalizados? Tenho perguntas como “onde você nos conheceu”, que tem caixas de seleção para permitir várias escolhas, e outra que pergunta como eles gostariam de ser contatados por e-mail, SMS e correio.
Obrigado
Clement

Nenhuma das consultas acima lhe dará exatamente o que você procura. Sem escrever uma nova consulta, a melhor abordagem seria executar a primeira consulta que postei várias vezes. Execute-a uma vez para cada um dos seus campos personalizados. Insira o nome do campo na entrada field_name da consulta. A consulta a que me refiro é esta:

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