三个非常相关的SQL问题(我实际上正在使用mySQL):
假设一个人员表有两列名称,国家
1)我如何向有同胞的人展示?我可以按国家/地区显示公民人数:
select country, count(*) as fellow_citizens
from people
group by country
但我似乎无法显示那些与其他人相关的记录> 1.以下内容无效:
select name, country, count(*) as fellow_citizens
from people
group by country
where fellow_citizens > 1;
......并且不会是我想要的任何方式,因为我不想将人们分组。
2)为了解决上述问题,我有了将fellow_citizens存储在新列中的想法。 这听起来像是MySQL: Count records from one table and then update another等问题的变体。不同之处在于我想更新同一个表。
然而,那里给出的答案在这里不起作用:
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中做到这一点而不需要完整的程序代码?
答案 0 :(得分:2)
1 - >
select country, count(*) as fellow_citizens
from people
group by country
having fellow_citizens > 1
很抱歉,但无法理解第2点和第3点。
答案 1 :(得分:2)
您的选择查询应如下所示:
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)
答案 2 :(得分:1)
您是否尝试过这两个问题
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查询;但我认为这可以解决你的问题
答案 3 :(得分:1)
我会这样做。
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