SQL:计算(并填充?)有序结果之间的差异

时间:2014-04-17 18:22:51

标签: mysql sql

我使用MariaDB(根据我的有限概念,是MySQL的替代品)来支持一些选举申请。

我与候选人存储的一件事是"领先保证金" - 即,他们的多数是多少。如果候选人A获胜6票,候选人B获胜12票,候选人C获胜7票,则值为0,5,0。

但是现在我有了一个很大的新数据集,我知道了里程数和选票,但是没有任何内容可以用于#34; leadingmargin"。有数百名候选人,所以我需要计算一下。这就是我用英语的意思:

  1. 骑马排序所有人。
  2. 然后按投票排序。
  3. 减去(排名第一的候选人的选票 - 排名第二的候选人的选票)并将结果存储在"领先的边际"排名第一的专栏。
  4. 其他人都得到0.或者只留下它。
  5. 这是一个完整表格的示例,用于展示我的目标。它与真实数据之间的唯一区别在于我还没有计算出"领先的保证金。

    MariaDB [databasename]> SELECT * FROM `demo_candidates` ORDER BY `riding` ASC , `votes` DESC;
    +--------+-----------+-----------+---------+-------+-------+---------------+---------+
    | id     | riding    | lname     | fname   | party | votes | leadingmargin | percent |
    +--------+-----------+-----------+---------+-------+-------+---------------+---------+
    |      1 |         1 | Redford   | Richard |     1 |    92 |            50 |   57.14 |
    |      4 |         1 | Pelford   | Paul    |     4 |    42 |             0 |   26.09 |
    |      3 |         1 | Yeltmate  | Yoris   |     3 |    16 |             0 |    9.94 |
    |      2 |         1 | Gint      | Ginny   |     2 |    11 |             0 |    6.83 |
    |      6 |         2 | Gelford   | Gippy   |     2 |    99 |            16 |   44.59 |
    |      5 |         2 | Roberts   | Roy     |     1 |    83 |             0 |   37.39 |
    |      8 |         2 | Peg       | Porkay  |     4 |    28 |             0 |   12.61 |
    |      7 |         2 | Yavin     | Yordy   |     3 |    12 |             0 |    5.41 |
    etc..
    +--------+-----------+-----------+---------+-------+-------+---------------+---------+
    20 rows in set (0.00 sec)
    

1 个答案:

答案 0 :(得分:1)

此查询仅设置获胜者的主要保证金。如果将leadingmargin的DEFAULT值设置为0,或者运行另一个查询以将其设置为0,那么你就会很好:

UPDATE demo_candidates t1
LEFT JOIN demo_candidates t2
  ON t2.riding = t1.riding
  AND t2.votes > t1.votes
JOIN demo_candidates t3
  ON t3.riding = t1.riding
  AND t3.votes < t1.votes
LEFT JOIN demo_candidates t4
  ON t4.riding = t3.riding
  AND t4.id <> t1.id
  AND t4.votes > t3.votes
SET t1.leadingmargin = t1.votes - t3.votes
WHERE t2.id IS NULL AND t4.id IS NULL

如果获胜者有平局或者只有一名候选人,则不会设置领先保证金。

<强>更新

这个也设置了0

UPDATE demo_candidates t1
LEFT JOIN demo_candidates t2
  ON t2.riding = t1.riding
  AND t2.votes > t1.votes
LEFT JOIN demo_candidates t3
  ON t3.riding = t1.riding
  AND t3.votes < t1.votes
LEFT JOIN demo_candidates t4
  ON t4.riding = t3.riding
  AND t4.id <> t1.id
  AND t4.votes > t3.votes
SET t1.leadingmargin = IF(t2.id IS NULL AND t4.id IS NULL, t1.votes - t3.votes, 0)