【问题标题】:Totalling up ballot results汇总投票结果
【发布时间】:2011-09-30 07:16:48
【问题描述】:

我有一张选票,每个选民有 3 张选票,从 10 位不同的候选人中进行选择。第1票得3分,第2票得2分,第3票得1分。

我有以下 SQL 查询来计算从每个投票中获得的点数(因此将投票 1、2 和 3 的结果分开)。

我需要做的是将所有这些结果放在一个表中,但我不太确定从哪里开始。

SELECT cn.cand_name, (count(vote_1) * 3) as vote_1 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_1 = cn.cand_number GROUP BY cand_name;

SELECT cn.cand_name, (count(vote_2) * 2) as vote_2 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_2 = cn.cand_number GROUP BY cand_name;

SELECT cn.cand_name, (count(vote_3) * 1) as vote_3 FROM candidate_votes cv Inner Join candidate_names cn ON cv.vote_3 = cn.cand_number GROUP BY cand_name;

我有以下结果表:

Voter_number    Vote_1     Vote2      Vote3
123             cand_1     cand_3     cand_2
456             cand_2     cand_1     cand_3
789             cand_2     cand_3     cand_1

还有如下候选名表:

cand_number     cand_name
cand_1          Dave
cand_2          Sarah
cand_3          Nigel

所以我正在寻找的结果将类似于:

Candidate       Votes
Dave            6
Sarah           7
Nigel           5

【问题讨论】:

    标签: sql-server count


    【解决方案1】:
    SELECT
        cn.cand_name, 
        count(cv1.vote_1) * 3 as vote_1, 
        count(cv2.vote_2) * 2 as vote_2, 
        count(cv3.vote_3) as vote_3
    FROM
        candidate_names cn
        LEFT JOIN
        candidate_votes cv1 ON cv1.vote_1 = cn.cand_number
        LEFT JOIN
        candidate_votes cv2 ON cv2.vote_2 = cn.cand_number
        LEFT JOIN
        candidate_votes cv3 ON cv3.vote_3 = cn.cand_number
    GROUP BY cn.cand_name;
    

    这也允许您添加所有投票

    (count(cv1.vote_1) * 3) +
        (count(cv2.vote_2) * 2) +
        count(cv3.vote_3) as totalvotes
    

    编辑:行乘以 JOIN,这就是 cand2 和 cand3 错误的原因

    SELECT
        cn.cand_name, 
        SUM(CASE WHEN cv.vote_1 = cn.cand_number THEN 3 ELSE 0 END) as vote_1, 
        SUM(CASE WHEN cv.vote_2 = cn.cand_number THEN 2 ELSE 0 END) as vote_2, 
        SUM(CASE WHEN cv.vote_3 = cn.cand_number THEN 1 ELSE 0 END) as vote_3
    FROM
        candidate_names cn
        JOIN
        candidate_votes cv ON cn.cand_number IN (cv.vote_1, cv.vote_2, cv.vote_3)
    GROUP BY cn.cand_name;
    

    【讨论】:

    • @Tom:我的加权乘法有误。请立即尝试
    • 我已经注意到并且已经更正了它......它仍然没有给出正确的结果。
    • @Tom:好吧,“结果错误”没有帮助。没有样本数据,也没有迹象表明出了什么问题(值错误?候选人太多?)。
    • 你的方法给出了 Dave=6, Sarah=8, Nigel=6
    【解决方案2】:
    SELECT cn.cand_name
         , COALESCE(cv1.cnt_1,0)
         , COALESCE(cv2.cnt_2,0)
         , COALESCE(cv3.cnt_3,0)
         , 3*COALESCE(cv1.cnt_1,0) + 2*COALESCE(cv2.cnt_2,0)
           + 1*COALESCE(cv3.cnt_3,0) AS total
    FROM candidate_names AS cn
      LEFT JOIN 
        ( SELECT vote_1 AS vote
               , COUNT(*) AS cnt_1
          FROM candidate_votes cv
          GROUP BY vote_1
        ) AS cv1
        ON cv1.vote = cn.cand_number
      LEFT JOIN 
        ( SELECT vote_2 AS vote
               , COUNT(*) AS cnt_2
          FROM candidate_votes cv
          GROUP BY vote_2
        ) AS cv2
        ON cv2.vote = cn.cand_number
      LEFT JOIN 
        ( SELECT vote_3 AS vote
               , COUNT(*) AS cnt_2
          FROM candidate_votes cv
          GROUP BY vote_3
        ) AS cv3
        ON cv3.vote = cn.cand_number
    

    【讨论】:

    • ypercube 最有效的查询
    【解决方案3】:
    SELECT
      Candidate = n.cand_name,
      Votes = SUM(s.vote_weight)
    FROM (
      SELECT
        cand_number = CASE x.weight
          WHEN 1 THEN Vote3
          WHEN 2 THEN Vote2
          WHEN 3 THEN Vote1
        END,
        vote_weight = x.weight
      FROM candidate_votes v
        CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) x (weight)
    ) s
      INNER JOIN candidate_names n ON s.cand_number = n.cand_number
    GROUP BY n.cand_name
    

    【讨论】:

      猜你喜欢
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 2011-03-24
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多