2013-06-11 2 views
2

Я как-то новичок в SQL, и у меня есть приложение для выбора. Я сделал 80% этого и теперь застрял при подсчете голосов от 2 или более столбцов.SQL - подсчет от 2 или более столбцов

Пример таблицы:

|**Senator_1** | **Senator_2** | **Senator_3**| 
---------------------------------------------- 
    George  | Carl  | Anthony 
    Carl  | Tony  | Stark 
    Anthony  | George  | Tony 
    Anthony  | George  | Stark 

Я хотел бы иметь такой результат.

|**Candidate_Name** | **Vote_Count**| 
------------------------------------- 
    George   | 3 
    Anthony   | 3 
    Carl    | 2 
    Stark   | 2 
    Tony    | 2 

Я действительно не имею ни малейшего представления о том, какой запрос я собираюсь использовать. Любые идеи решения этого?

Кстати, за путаницу и все аргументы, которые начали здесь, я буду объяснять:

Я хотел быть прямо к моей проблеме, поэтому я просто разместил образец таблицы. У меня есть таблица для избирателей, кандидатов и избирателей. У всех таблиц есть свой идентификатор и т. Д., Поэтому я уверен, что это нормализовано.

+0

На что я смотрю? Что представляют данные в первой таблице? –

+2

Даже не зная, я могу сказать вам сразу с места в карьер, у вас есть некоторые серьезные недостатки дизайна в ваших данных. –

+0

@StevenMoseley Я предполагаю, что каждый голос является голосованием за 3 кандидата, и он хочет подсчитать общее количество голосов на одного кандидата. –

ответ

11

Основной вопрос, который у вас есть, - это ваш стол, который не нормализуется. Я настоятельно рекомендую вам исправить вашу текущую структуру таблицы. возможно новая структура таблицы будет:

/* Table for unique voters */ 
CREATE TABLE voters (
    id INT UNSIGNED NOT NULL PRIMARY KEY, 
    name VARCHAR(255) NOT NULL 
) ENGINE=InnoDB; 

/* Table for unique candidates */ 
CREATE TABLE candidates (
    id INT UNSIGNED NOT NULL PRIMARY KEY, 
    name VARCHAR(255) NOT NULL 
) ENGINE=InnoDB; 

/* Many-to-many table storing votes by voters for candidates */ 
CREATE TABLE votes (
    voter_id INT UNSIGNED NOT NULL, 
    candidate_id INT UNSIGNED NOT NULL, 
    PRIMARY KEY (voter_id, candidate_id), 
    CONSTRAINT FOREIGN KEY (voter_id) REFERENCES voters (id), 
    CONSTRAINT FOREIGN KEY (candidate_id) REFERENCES candidates (id) 
) ENGINE=InnoDB; 

/* Populate data */ 
INSERT INTO voters (name) 
VALUES ('Voter 1'), ('Voter 2'), ('Voter 3'), ('Voter 4'); 

INSERT INTO candidates (name) 
VALUES ('George'), ('Carl'), ('Anthony'), ('Tony'), ('Stark'); 

INSERT INTO votes (voter_id, candidate_id) 
VALUES (1,1), (1,2), (1,3), 
     (2,2), (2,4), (2,5), 
     (3,3), (3,1), (3,4), 
     (4,3), (4,1), (4,5); 

Тогда вы могли бы легко получить результат путем объединения двух таблиц:

/* query showing all voters and the candidates they voted for */ 
SELECT voters.name, candidates.name 
FROM votes 
    INNER JOIN voters on votes.voter_id = voters.id 
    INNER JOIN candidates ON votes.candidate_id = candidates.id; 

/* Finally, a query showing votes per candidate */ 
SELECT candidates.name, COUNT(*) AS votes 
FROM votes 
    INNER JOIN candidates ON votes.candidate_id = candidates.id 
GROUP BY candidates.id; 

См SQL Fiddle with Demo

Однако, если вы не можете изменить дизайн таблицы, то вы можете получить результат, не открывая данные, которые у вас есть в нескольких столбцах. Вы можете использовать UNION ALL, чтобы UNPIVOT в несколько столбцов в строки, чтобы получить количество:

select name, count(*) TotalVotes 
from 
(
    select senator_1 name 
    from yt 
    union all 
    select senator_2 name 
    from yt 
    union all 
    select senator_3 name 
    from yt 
) d 
group by name 
order by totalVotes desc; 

См SQL Fiddle with Demo

+0

Undid my -1, но все же нехорошо увековечить плохой дизайн. –

+0

@StevenMoseley Я согласен с тем, что идеальным решением будет исправление структуры таблицы. Это решение их существующей проблемы. – Taryn

+0

@StevenMoseley Это полностью ваше решение не до +1 этого. Я предлагаю решение их проблемы, отметим, что я также посоветовал им изменить их дизайн, и я в процессе написания альтернативного дизайнерского решения. – Taryn

0

Я думаю, что вы хотите, чтобы подсчитать общее NO. появления каждого имени в разных столбцах. Исходя из этого, я думаю, что что-то вроде ниже может помочь -

select senator, sum(cnt) as 'count' from (
select senator_1 as 'senator', count(1) 'cnt' from election_table group by senator_1 
union all 
select senator_2 as 'senator', count(1) 'cnt' from election_table group by senator_2 
union all 
select senator_3 as 'senator', count(1) 'cnt' from election_table group by senator_3 
) x group by x.senator 
Смежные вопросы