我正在尝试开发一个需要高级数据库查询的投票应用程序。该应用程序允许用户使用他们的电话号码给其他用户投票。因此,请确保拥有多个电话号码的用户将他们的所有选票统计在一起,我有一张表格将他们的电话号码与他们的国民身份证号码相关联。最后我有两个表:
user_national_id 表
用户电话号码 |国家代码
------------------ | ------------------
phone1 | nat_id1
phone2 | nat_id1
投票表
用户电话号码 |发件人
------------------ | ------------------
phone1 |发件人1
phone1 |发件人2
phone2 |发件人3
phone2 |发件人2
我现在需要一种方法,在 user_national_id 表中收集唯一的国民 ID 号,将国民 ID 与 user_national_id 表中的用户电话号码相关联,然后计算返回的电话号码在 votes 表中出现的次数。
提前致谢。
(从评论中移...)
DELIMITER $$
CREATE PROCEDURE GetUniqueNominees()
BEGIN DECLARE done BOOLEAN;
DECLARE nomIds VARCHAR(255);
DECLARE curIds CURSOR FOR
SELECT DISTINCT national_id
FROM user_national_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
OPEN curIds;
LOOPROWS: LOOP
IF done=TRUE THEN
CLOSE curIds;
LEAVE LOOPROWS;
END IF;
FETCH curIds
INTO nomIds;
SELECT DISTINCT nomIds;
select count(user_phone_no)
from votes
inner join user_national_id
ON (votes.user_phone_no = user_national_id.user_phone_no)
where national_id=nomIds;
END LOOP;
END$$
DELIMITER ;
最佳答案
SQL 通常不需要循环和游标,而且通常(尽管不总是),当您认为需要它们时,实际上并不需要。
SQL 不是过程性的,它是声明性的:你告诉服务器你想要什么——而不是服务器应该如何得到它。服务器(查询优化器)随后可以自由实现它可以想到的任何逻辑来计算结果,只要它在逻辑上与您的要求一致即可。
在这种情况下,以下是表达您似乎要问的内容的方式:
SELECT u1.national_id, COUNT(DISTINCT v.sender) AS votes_counted
FROM user_national_id u1
JOIN user_national_id u2 ON u2.national_id = u1.national_id
JOIN votes v ON v.user_phone_no = u2.user_phone_no
WHERE u1.user_phone_no = ?
GROUP BY u1.national_id
在这里,我们使用 user_national_id 表的两个“虚拟副本”,别名为 u1 和 u2。我们在 u1 中找到输入的电话号码,它给出了用户的国家 ID。由此,我们在 u2 中找到相同的国家 ID,它为我们提供了用户电话号码的所有,然后我们从那里计算(通过计算发件人)所有电话号码与电话匹配的投票数我们根据 u1 的标准在 u2 中找到的数字。我们计算 DISTINCT
发件人,它丢弃重复的投票,因为当前结构似乎允许我为用户的不同电话号码投票,但我认为这些应该被忽略。如果不是,请删除 DISTINCT
。
DISTINCT
是 SQL 新手通常滥用的另一个功能,这通常是“我的查询是错误的,但出于某种原因这似乎可以解决问题”的标志。不要随便、马虎、常规使用,不要无正当理由使用。在这里,理由似乎很明显。
关于mysql过程/函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40234221/