Il peut être très difficile de convaincre vos utilisateurs de voter dans un sondage — surtout si vous souhaitez toucher vos visiteurs occasionnels qui ne passent que de temps en temps.
À cette fin, je trouve qu’il est très utile de savoir qui n’a pas encore voté dans un sondage. Cela me permet de les relancer facilement, sans harceler ceux qui ont déjà voté.
J’ai affiné cette requête pour qu’elle soit facile à utiliser à partir de l’URL du sujet/message, car post.id est vraiment contraignant ! Et poll.name prend généralement la valeur « poll » par défaut s’il n’y a qu’un seul sondage par message de toute façon. Elle inclut les adresses e-mail, pour permettre l’envoi d’e-mails directs si nécessaire. Mais cela pourrait être facilement supprimé.
-- [params]
-- group_id :group_id
-- int :topic_id
-- int :post_number = 1
-- string :poll_name = poll
WITH target_post AS (
SELECT id AS post_id
FROM posts
WHERE topic_id = :topic_id
AND post_number = :post_number
),
poll_check AS (
SELECT COUNT(*) AS poll_count
FROM polls p
INNER JOIN target_post tp ON tp.post_id = p.post_id
WHERE p.name = :poll_name
),
voters AS (
SELECT DISTINCT pv.user_id AS voter_id
FROM poll_votes pv
INNER JOIN polls p ON p.id = pv.poll_id
INNER JOIN target_post tp ON tp.post_id = p.post_id
CROSS JOIN poll_check pc
WHERE p.name = :poll_name
AND 1 / pc.poll_count > 0 -- errors if poll_count = 0
)
SELECT
u.id AS user_id,
u.username,
ue.email
FROM users u
INNER JOIN group_users gu ON gu.user_id = u.id
INNER JOIN groups g ON g.id = gu.group_id
INNER JOIN user_emails ue ON ue.user_id = u.id AND ue.primary = TRUE
CROSS JOIN poll_check pc
WHERE g.id = :group_id
AND u.id > 0
AND 1 / pc.poll_count > 0 -- errors if poll_count = 0
AND NOT EXISTS (SELECT 1 FROM voters v WHERE v.voter_id = u.id)
ORDER BY u.username