为了完成我今天的MySQL问题,我想就此事提出一些建议。我有一个表,我需要添加一个具有计算值的列。我不打算更新表格 - 只是结合信息。 与我合作的表格看起来像这样:
+----------------+----------------+--------------------------------------+
| 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。这是我正在使用的查询:
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;
我如何实现我正在寻找的结果?
答案 0 :(得分:1)
我无法破译您的查询所做的事情,以及为什么要这样做。
看起来只有一个"阈值&#34 ;;这是根据针对votes
表的查询计算得出的。
如果目标是返回"阈值"之间的非正差异。价值和" orginal_votes"每个候选人的价值,我会这样做:
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
。
看起来你只想比较" original_votes"对于每个vote_candidate到"阈值"值。看起来好像所有这些子查询都是完全没必要的;他们只会造成混乱。
如果您想避免使用MySQL LEAST()
函数,并使用ANSI标准CASE
表达式,那么您可以
替换这个:
LEAST(0,t.threshold - c.original_votes)
用这个:
CASE
WHEN t.threshold < c.original_votes
THEN t.threshold - c.original_votes
ELSE 0
END