首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当MySQL中的循环返回错误的值时

当MySQL中的循环返回错误的值时
EN

Stack Overflow用户
提问于 2014-06-11 21:07:47
回答 1查看 275关注 0票数 1

为了完成我今天的MySQL问题,我想得到一些关于这个问题的建议。我有一个表,需要向其中添加一个具有计算值的列。我不想更新表格-只是合并信息。和我一起工作的桌子是这样的:

代码语言:javascript
复制
        +----------------+----------------+--------------------------------------+
        | VOTE_CANDIDATE | ORIGINAL_VOTES | SURPLUS_REDISTRIBUTION_TO_CANDIDATES |
        +----------------+----------------+--------------------------------------+
        |              1 |              8 |                                   -1 |
        |              2 |              1 |                                   -1 |
        |              3 |              2 |                                   -1 |
        |              4 |              4 |                                   -1 |
        |              5 |              2 |                                   -1 |
        |              6 |              3 |                                   -1 |
        +----------------+----------------+--------------------------------------+

我的问题是,只有第1行应该在列SURPLUS_REDISTRIBUTION_TO_CANDIDATES上返回-1,因为它的ORIGINAL_VOTES大于7的阈值,其余的应该返回零(在低于状态时),因为它低于阈值。好像查询锁定了第一行,然后在所有行上重用SURPLUS_REDISTRIBUTION_TO_CANDIDATES。这是我正在处理的查询:

代码语言:javascript
复制
SELECT vote_candidate, COUNT(*) original_votes, CASE
  WHEN (
    (
      SELECT MAX(
        (
          SELECT COUNT(*) votes_above_the_threshold
          FROM vote_orders
        )
      ) votes
      FROM vote_orders
      WHERE vote_order = 1
    ) >= (
      SELECT FLOOR((COUNT(*) / (2 + 1)) + 1) threshold
      FROM votes
    )
  )
  THEN (
    SELECT FLOOR((COUNT(*) / (2 + 1)) + 1) threshold
    FROM votes
  ) - (
    SELECT MAX(votes_above_the_threshold) votes
    FROM (
      SELECT vote_candidate vote_candidate, COUNT(*) votes_above_the_threshold
      FROM vote_orders
      WHERE vote_order = 1
      GROUP BY vote_candidate
      HAVING votes_above_the_threshold >= (
        SELECT FLOOR((COUNT(*) / (2 + 1)) + 1) threshold
        FROM votes
      )
    ) t
    WHERE votes_above_the_threshold = (
      SELECT MAX(votes_above_the_threshold)
      FROM vote_orders
    )
  )
  ELSE 0
END surplus_redistribution_to_candidates
FROM vote_orders
WHERE vote_order = 1
GROUP BY vote_candidate;

我怎样才能达到我想要的结果?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-11 21:49:54

我很难理解您的查询是干什么的,以及它为什么要做它所做的事情。

它看起来只有一个“阈值”;它是作为对votes表的查询的表达式计算出来的。

如果目标是返回每个候选人的“阈值”值和"orginal_votes“值之间的非正差,我将这样做:

代码语言:javascript
复制
SELECT c.vote_candidate
     , c.original_votes
     , LEAST(0,t.threshold - c.original_votes) AS surplus_redistribution_to_candidates
  FROM ( SELECT o.vote_candidate
              , COUNT(*) original_votes
           FROM vote_orders o
          WHERE o.vote_order = 1
          GROUP
             BY o.vote_candidate
       ) c
 CROSS
  JOIN ( SELECT FLOOR((COUNT(*) / (2 + 1)) + 1) AS threshold
           FROM votes
        ) t
 ORDER BY c.vote_candidate

以c为别名的内联视图获得每个候选对象的"original_votes“,内联视图别名为"t”,获得“阈值”。外部查询比较这两个值,并返回差额(如果是负值)或零。

我不认为您的查询锁定了第一行。相反,我认为问题在于,这些SELECT MAX()子查询的每次执行都会为每个vote_candidate返回相同的值。其巧合之处在于,最大值恰好与结果集中的“第一个”vote_candidate相关联。

看起来,您只是想将每个vote_candidate的“vote_candidate”值与“阈值”值进行比较。看起来,所有这些子查询都是完全没有必要的;它们只是造成了混乱。

如果要避免使用MySQL LEAST()函数,并使用ANSI标准CASE表达式,则可以

代之以:

代码语言:javascript
复制
    LEAST(0,t.threshold - c.original_votes)

在这方面:

代码语言:javascript
复制
    CASE
    WHEN t.threshold < c.original_votes
    THEN t.threshold - c.original_votes
    ELSE 0
    END
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24172600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档