2

私はどういうわけかSQLに不慣れで、選挙アプリケーションを持っています。私はそれの 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 などがあるので、正規化されていると確信しています。

4

2 に答える 2

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);

次に、2 つのテーブルを結合することで簡単に結果を得ることができます。

/* 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 を参照してください

ただし、テーブルのデザインを変更できない場合は、複数の列にあるデータのピボットを解除することで結果を得ることができます。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;

デモで SQL Fiddle を参照してください

于 2013-06-11T13:01:05.617 に答える
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
于 2013-06-11T13:01:28.390 に答える