Is it possible to see who voted in polls?

I just tested out polls for the first time in a while, and it works quite well and I like it.

But I would like to have an open poll so we can see who voted for which option. Is this possible? Is there any way to see who voted for what?

You can run the following query to get a list of users who voted and their selected poll options.
Please choose the appropriate query for your Discourse version.

Query for Discourse v2.2.0.beta5 and newer

-- [params]
-- post_id :post_id
-- text :poll_name = poll

SELECT u.id AS user_id, u.username, v.poll_option_id AS option_id, o.html AS option_html
FROM polls p
       JOIN poll_votes v ON (p.id = v.poll_id)
       JOIN poll_options o ON (o.id = v.poll_option_id)
       JOIN users u ON (v.user_id = u.id)
WHERE p.post_id = :post_id AND p.name = :poll_name
ORDER BY u.username, v.poll_option_id

Query for older versions of Discourse up to v2.2.0.beta4

-- [params]
-- post_id :post_id
-- text :poll_name = poll

SELECT votes.user_id, users.username, votes.option_id, options.html AS option_html
FROM (
  SELECT value1 ->> 'id' AS id,
    value1 ->> 'html' AS html
  FROM (
    SELECT json_array_elements(value :: JSON -> :poll_name -> 'options') AS value1
    FROM post_custom_fields
    WHERE post_id = :post_id AND name = 'polls' AND value :: JSON -> :poll_name ->> 'name' = :poll_name
  ) option_values
) options
       JOIN (
  SELECT key :: INTEGER AS user_id,
    trim(json_array_elements(value :: JSON -> :poll_name) :: TEXT, '"') AS option_id
  FROM json_each((
    SELECT value :: JSON
    FROM post_custom_fields
    WHERE post_id = :post_id AND name LIKE 'polls-votes'
  ))
) votes ON (options.id = votes.option_id)
       JOIN users ON (votes.user_id = users.id)
ORDER BY users.username, votes.option_id

How to find post_id

You can use the following query if you need to find the right post_id.

-- [params]
-- topic_id :topic_id
-- int :post_number = 1

SELECT id
FROM posts
WHERE topic_id = :topic_id AND post_number = :post_number

it works! thanks so much. :fireworks:

is there a query for quickly identifying the post ID containing polls? I used the .json URL method but it was surprisingly cumbersome to find the right post within it.

Default values are specified like this:

I updated the query. It’s now a lot simpler. :slight_smile:

C’è un modo per filtrare i risultati in base all’età dell’account?

Ad esempio, se un account ha meno di 60 giorni, non dovrebbe apparire nei risultati? O forse esiste un modo per creare un sondaggio che limiti chi può votare in base all’età dell’account?

Stiamo cercando di prevenire possibili brogli elettorali da parte di account appena creati per un’importante votazione in arrivo.

È un caso d’uso molto interessante. Penso che dovremmo avere un’opzione per impedire agli utenti TL0 di votare in un sondaggio @zogstrip!

C’è un parametro che potrei aggiungere alla stringa di ricerca di @gerhard per non mostrare gli utenti al di sotto di un certo livello di fiducia o età dell’account nella query?

Anche se dovessi contare manualmente i voti in base ai risultati, sarebbe più veloce rispetto al dover controllare manualmente l’età di ogni account e i loro voti.

Ecco una query per impostare un livello di fiducia minimo per gli utenti.

-- [params]
-- post_id :post_id
-- text :poll_name = poll
-- integer :min_trust_level

SELECT u.id AS user_id, u.username, v.poll_option_id AS option_id, o.html AS option_html
FROM polls p
       JOIN poll_votes v ON (p.id = v.poll_id)
       JOIN poll_options o ON (o.id = v.poll_option_id)
       JOIN users u ON (v.user_id = u.id)
WHERE p.post_id = :post_id AND p.name = :poll_name
  AND u.trust_level >= :min_trust_level
ORDER BY u.username, v.poll_option_id

Ecco una query per mostrare solo gli utenti registrati da un certo numero di giorni.

-- [params]
-- post_id :post_id
-- text :poll_name = poll
-- integer :days_ago = 30

SELECT u.id AS user_id, u.username, v.poll_option_id AS option_id, o.html AS option_html
FROM polls p
       JOIN poll_votes v ON (p.id = v.poll_id)
       JOIN poll_options o ON (o.id = v.poll_option_id)
       JOIN users u ON (v.user_id = u.id)
WHERE p.post_id = :post_id AND p.name = :poll_name
  AND u.created_at < NOW() - INTERVAL ':days_ago days' 
ORDER BY u.username, v.poll_option_id

Fantastico :heart_eyes: @gerhard grazie!

Tieni presente che questa query è ora inclusa nelle query di Data Explorer predefinite, che vengono installate automaticamente, quindi non devi inserire questo codice manualmente!

Un altro modo per trovare l’ID del post, specialmente se si tratta del primo post, è guardare <topic_url>.json (ad esempio, Is it possible to see who voted in polls?). È abbastanza semplice trovare l’ID del post all’inizio di quel file JSON.

@nbianca puoi aggiungere alla tua lista un nuovo parametro per i sondaggi min_trust_level che consenta ai creatori di sondaggi di limitare chi può votare in base al proprio livello di fiducia?

L’opzione dovrebbe essere disponibile nell’interfaccia del costruttore di sondaggi e dovrebbe esserci un messaggio chiaro che spiega perché alcuni utenti non possono votare in quel sondaggio.

Non è nemmeno necessario trovare l’ID del post, poiché ora c’è un pulsante di esportazione per i sondaggi disponibile per lo staff.

Questa funzionalità è stata implementata, ma in modo leggermente diverso da quanto richiesto. I sondaggi accettano un’opzione groups invece di min_trust_level, che richiede un elenco di nomi di gruppi separati da virgole (ad esempio trust_level_2,staff per consentire il voto a chi ha un livello di fiducia 2 o superiore e a tutti i membri dello staff).

Mi dispiace, ma per me è troppo confuso. Puoi spiegarmelo in modo più semplice?