简体   繁体   中英

How to make the equivalent of DISTINCT in query counting results

My table stores a set of survey results, which I am outputting to a results page using this query:

SELECT a.question_one AS answer, q1.ct AS q1_count, q2.ct AS q2_count, q3.ct AS q3_count 
FROM vote_entries 
AS a 
INNER JOIN (SELECT question_one, count(question_one) AS ct from vote_entries group by question_one) q1 on q1.question_one=a.question_one 
INNER JOIN (SELECT question_two, count(question_two) AS ct FROM vote_entries group by question_two) q2 on q2.question_two=a.question_one 
INNER JOIN (SELECT question_three, count(question_three) AS ct FROM vote_entries group by question_three) q3 on q3.question_three=a.question_one 
GROUP BY a.question_one

This works how I want it to, but I have just noticed that some people have submitted more than once from the same email address. I want to filter these people out so that only one of their responses is included.

Essentially I want to have something like WHERE DISTINCT email , but of course that doesn't exist. Does anyone know how I can achieve what I am trying to do, preferrably in this one query?

This is my table structure:

CREATE TABLE IF NOT EXISTS `vote_entries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(128) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `name` varchar(128) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `question_one` varchar(32) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `question_two` varchar(32) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `question_three` varchar(32) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

An example of the data looks like the below. The user can select one of three options in a radio button set for each of the questions.

+----+------------------+------------+--------------+--------------+----------------+
| id |      email       |    name    | question_one | question_two | question_three |
+----+------------------+------------+--------------+--------------+----------------+
|  1 | test@email.com   | John Doe   | RIC          | RIC          | RIC            |
|  2 | test2@email.com  | Jane Smith | BAR          | BAR          | BAR            |
|  3 | test2@email.com  | Jane Smith | BAR          | BAR          | BAR            |
|  4 | sample@email.com | Kelly Doe  | Existing     | Existing     | Existing       |
+----+------------------+------------+--------------+--------------+----------------+

The issue is, if Jane Smith submits her answer twice, it's going to skew the results unfairly. But I don't want to encourage people to make fake email addresses to submit more than once, either - so a frontend solution of some sort is not what I'm lookign for.

I would recommend conditional aggregation. This may be a simpler way to to do what you want:

select a.answer,
       count(distinct case when a.answer = ve.question_one then ve.email) as q1_count,
       count(distinct case when a.answer = ve.question_two then ve.email) as q2_count,
       count(distinct case when a.answer = ve.question_three then ve.email) as q3_count
from (select distinct ve.question_one as answer
      from vote_entries ve
     ) a cross join
     vote_entries ve
group by a.answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM