[英]MySQL: count records by value and then update another column with their count
三个非常相关的SQL问题(我实际上使用的是mySQL):
假设一个人员表有两列名称,国家
1)我如何向有同胞的人展示? 我可以按国家显示公民人数:
select country, count(*) as fellow_citizens
from people
group by country
但是我似乎无法显示其中fellow_citizens> 1的记录。以下内容无效:
select name, country, count(*) as fellow_citizens
from people
group by country
where fellow_citizens > 1;
......因为我不想把人分组,所以不会是我想要的任何方式。
2)为了解决上述问题,我有了将fellow_citizens存储在新列中的想法。 这听起来像是MySQL等问题的变体:从一个表中计算记录然后更新另一个表 。 不同之处在于我想更新同一个表。
但是那里给出的答案在这里不起作用:
update people as dest
set fellow_citizens =
(select count(*) from people as src where src.country = dest.country);
我收到此错误消息:
您不能在FROM子句中为更新指定目标表'dest'
看来我需要通过另一个临时表来做到这一点。 可以在没有临时表的情况下完成吗?
3)作为上述的变体,如何按国家/地区更新人员列? 我发现我可以通过以下方式更新全局计数器:
set @i:=0; update people set counter = @i:=@i+1 order by country;
但是,当国家的价值发生变化时,我想重置我的@i计数器。
有没有办法在mySQL中做到这一点而不需要完整的程序代码?
1 - >
select country, count(*) as fellow_citizens
from people
group by country
having fellow_citizens > 1
对不起,但不能真正理解第2点和第3点。
您的选择查询应如下所示:
SELECT name, country, count(*) as fellow_citizens
FROM people
GROUP BY country
HAVING fellow_citizens > 1;
推荐解决方案
你不想分组,你只想重复每个人的计数。
这些数据没有规范化,像这样的代码不是一个很好的方法。
但是,以下选择将为您提供所有人及其计数:
SELECT p.*
, s.fellow_citizens
FROM people p
INNER JOIN (
SELECT country, count(*) as fellow_citizens
FROM people
GROUP BY country
HAVING count(*) > 1) s ON (s.country = p.country)
如果您不想要实际计数,只需来自拥有1个以上公民的国家的人,另一种方式来编写此查询(这可能比以前的方法更快,您必须使用您的数据进行测试):
SELECT p.*
FROM people p
WHERE EXISTS
( SELECT *
FROM people p2
WHERE p2.country = p.country
AND p2.PK <> p.PK -- the Primary Key of the table
)
只有在你面临缓慢的情况下才能这样做
如果你想使用更新语句将计数包含在表中,我建议你使用一个单独的计数表,因为至少有一些规范化。
INSERT INTO people_counts (country, pcount)
SELECT p.country, count(*) as peoplecount
FROM people p
GROUP BY p.country
ON DUPLICATE KEY pcount = VALUES(pcount)
然后,您可以将计数表与人员数据一起加速选择。
SELECT p.*, c.pcount
FROM people p
INNER JOIN people_counts c ON (p.country = c.country)
你有没有尝试过这个问题
select name, fellow_citizens
from people left join
(select country, count(*) as fellow_citizens
from people group by country
having fellow_citizens > 1) as citizens
on people.country = citizens.country
我不是很擅长编写sql查询; 但我认为这可以解决你的问题
我会这样做的。
create view citizencount as
select country, count(*) citizens
from people
group by country
然后您的查询变为(类似的东西)
select p.personid, p.country, cc.citizens -1 fellow_citizens
from people p
join citizencount cc on
cc.country = p.country
您可能想要添加
where fellow_citizens > 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.