在MySQL表中只计算一次或两次选票
我有下表:在MySQL表中只计算一次或两次选票,mysql,Mysql,我有下表: +-----------------+ | id| user | vote | +-----------------+ | 1 | 1 | text | | 2 | 1 | text2| | 3 | 2 | text | | 4 | 3 | text3| | 5 | 2 | text | +-----------------+ 我要做的是数一数“选票” 那很好。输出: +-------------------+
+-----------------+
| id| user | vote |
+-----------------+
| 1 | 1 | text |
| 2 | 1 | text2|
| 3 | 2 | text |
| 4 | 3 | text3|
| 5 | 2 | text |
+-----------------+
我要做的是数一数“选票”
那很好。输出:
+-------------------+
| count(vote)| vote |
+-------------------+
| 3 | text |
| 1 | text2|
| 1 | text3|
+-------------------+
但现在我只想计算用户的第一票或第一票和第二票。
所以我想要的结果是(如果我只算第一票):
我试着与count(distinct…)一起工作,但可以让它工作
有没有正确的提示?您可以在一条SQL语句中使用以下内容来完成此操作:
SELECT vote, COUNT(vote)
FROM
(
SELECT MAX(user), vote
FROM table1
GROUP BY user
) d
GROUP BY vote
请注意,这只会给您1票,而不是1票或2票。最简单的方法是使用问题中列出的“行编号”解决方案之一。那么您的原始查询就快到了:
SELECT
COUNT(vote),
vote
FROM tableWithRowNumberAdded
WHERE MadeUpRowNumber IN (1,2)
GROUP BY vote
我的另一个选择是更冗长,需要工作台。这些可以是模式中的“真实”表,也可以是您熟悉的任何中间结果集
从每个用户的第一次投票开始:
SELECT user, min(id) FROM table GROUP BY user
把这个放在工作台上;让我们称之为第一次投票。接下来,我们可以获得每个用户的第二次投票,如果有的话:
SELECT user, min(id) FROM table WHERE id not in (select id from FirstVote) GROUP BY user
让我们来看看第二次投票的结果。UNION FirstVote到SecondVote,将其加入原始表并按投票分组。这是你的答案
SELECT
vote,
COUNT(*)
FROM table
INNER JOIN
(
SELECT id FROM FirstVote
UNION ALL
SELECT id FROM SecondVote
) as BothVotes
ON BothVotes.id = table.id
GROUP BY vote
当然,它可以被构造为一个包含多个子查询的语句,但这对于维护或在本论坛中阅读来说都是非常可怕的。对于MySQL来说,这是一个非常棘手的问题。在其他系统上,有窗口函数:它在与当前行相关的一组表行上执行计算。
MySQL缺少这种功能。因此,我们应该寻找一个解决办法。以下是问题描述和建议的解决方案:
我还假设用户的前两次投票可以由Id决定:较早的投票具有较小的Id
基于此,我建议您采用以下解决方案:
SELECT
Vote,
Count (*)
FROM
Table,
(
SELECT
user_id, SUBSTRING_INDEX(GROUP_CONCAT(Id ORDER BY user_id ASC), ',', 2) AS top_IDs_per_user
FROM
Table
GROUP BY
user_id
) s_top_IDs_per_User
WHERE
Table.user_id = s_top_IDs_per_User.User_id and
FIND_IN_SET(Id, s_top_IDs_per_User.top_IDs_per_user)
GROUP BY Vote
;
无法理解您的第二个预期输出。怎么来的?这就是我想要的结果。所以它计算ID:1、3和4(所有其他ID都已由已经投票的用户投票)每个用户只投票2次,所以您需要包括所有3次投票。你为什么要排除“text2”?
SELECT
vote,
COUNT(*)
FROM table
INNER JOIN
(
SELECT id FROM FirstVote
UNION ALL
SELECT id FROM SecondVote
) as BothVotes
ON BothVotes.id = table.id
GROUP BY vote
SELECT
Vote,
Count (*)
FROM
Table,
(
SELECT
user_id, SUBSTRING_INDEX(GROUP_CONCAT(Id ORDER BY user_id ASC), ',', 2) AS top_IDs_per_user
FROM
Table
GROUP BY
user_id
) s_top_IDs_per_User
WHERE
Table.user_id = s_top_IDs_per_User.User_id and
FIND_IN_SET(Id, s_top_IDs_per_User.top_IDs_per_user)
GROUP BY Vote
;