我不熟悉SQL,我有一个Election Application。我已经完成了80%的工作,现在仍然坚持计算来自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
我真的不知道我将使用什么查询。解决这个问题的任何想法?
顺便说一句,对于混乱和从这里开始的所有论点,我将解释:
我想直接解决我的问题,这就是我刚发布样本表的原因。我有选民,候选人和投票的桌子。所有表都有它的ID等等,所以我很确定它是标准化的。
答案 0 :(得分: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;
但是,如果您无法更改表的设计,则可以通过取消忽略多列中的数据来获得结果。您可以使用UNION ALL将多列拆分为行以获取计数:
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;
答案 1 :(得分:0)
我认为你正在计算总数。在不同的列中出现每个名称。基于此,我认为下面的内容可能有所帮助 -
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