PostgreSql在group by和需要再添加两列之间存在冲突
问题: 找出恰好被一个国家包围的内陆国家。报告身份证 以及内陆国的名称,然后是其周围国家的id和名称 输出表:Query3 属性:PostgreSql在group by和需要再添加两列之间存在冲突,postgresql,Postgresql,问题: 找出恰好被一个国家包围的内陆国家。报告身份证 以及内陆国的名称,然后是其周围国家的id和名称 输出表:Query3 属性: c1id (landlocked country id) [INTEGER] c1name (landlocked country name) [VARCHAR(20)] c2id (surrounding country id) [INTEGER] c2name (surrounding country name) [VARCHAR(20)] O
c1id (landlocked country id) [INTEGER]
c1name (landlocked country name) [VARCHAR(20)]
c2id (surrounding country id) [INTEGER]
c2name (surrounding country name) [VARCHAR(20)]
Order by: c1name ASC
模式:
- 国家表包含世界上所有国家及其事实
- “cid”是国家的id
- “name”是国家的名称
- “高度”是国家的最高海拔点
- “人口”是指国家的人口
CREATE TABLE country ( cid INTEGER PRIMARY KEY, cname VARCHAR(20) NOT NULL, height INTEGER NOT NULL, population INTEGER NOT NULL);
- 邻居表提供了有关这些国家及其邻国的信息
- “国家”指第一个国家的cid
- “邻居”指与第一个国家相邻的国家的cid
- “长度”是指两个邻国之间的边界长度
SELECT c.cid AS c1id,
c.cname AS c1name
FROM country c
JOIN neighbour n
ON n.country = c.cid
GROUP BY c.cid,
c.cname
HAVING Count(n.neighbor) = 1;
问题是我还需要邻国的名称和国家id,因此我尝试这样做:
SELECT c.cid AS c1id,
c.cname AS c1name,
n.neighbor,
c2.cname
FROM country c
JOIN neighbour n
ON n.country = c.cid
JOIN country c2
ON n.neighbor = c2.cid
GROUP BY c.cid,
c.cname
HAVING Count(n.neighbor) = 1;
问题显然是因为n.Nexture和c2.cname不在group by子句中。如果我将它们添加到GROUPBY子句中,那么即使一个国家是多个邻国,计数(n.邻居)也会分别计算每个国家的邻国
例如,如果希腊(cid=1)与土耳其(cid=2)和德国(cid=3)相邻。加拿大(cid=4)与美国(cid=5)相邻,则第二个查询的输出将为
1 Greece 2 Turkey
1 Greece 3 Germany
4 Canada 5 USA
1希腊2土耳其
1希腊3德国
4加拿大5美国
而不是
4 Canada 5 USA
4加拿大5美国
我该如何着手解决这个问题呢?我认为最简单的方法是
- 解决“邻居”所需的连接,然后
- 将第一个查询加入结果
insert into country values
(1, 'Greece', 1, 1), (2, 'Turkey', 1, 1), (3, 'Germany', 1, 1),
(4, 'Canada', 1, 1), (5, 'USA', 1, 1);
insert into neighbour values
(1, 2, 1), (2, 1, 1), (1, 3, 1), (3, 1, 1),
(4, 5, 1), (5, 4, 1);
解析连接
select c1.cid , c1.cname as cname, c2.cid as nid, c2.cname as nname
from neighbour n
inner join country c1 on c1.cid = n.country
inner join country c2 on c2.cid = n.neighbor;
加入您的第一个查询
前四行与上面的查询相同
select c1.cid , c1.cname as cname, c2.cid as nid, c2.cname as nname
from neighbour n
inner join country c1 on c1.cid = n.country
inner join country c2 on c2.cid = n.neighbor
inner join (SELECT c.cid AS c1id,
c.cname AS c1name
FROM country c
JOIN neighbour n
ON n.country = c.cid
GROUP BY c.cid, c.cname
HAVING Count(n.neighbor) = 1) n2
on c1.cid = n2.c1id;
上面查询中的最后一个连接保证第一对列中的国家有一个邻居
cid cname nid nname
--
2 Turkey 1 Greece
3 Germany 1 Greece
4 Canada 5 USA
5 USA 4 Canada
cid cname nid nname
--
2土耳其1希腊
3德国1希腊
4加拿大5美国
5美国4加拿大
哇,太谢谢你了!你解释得很清楚! cid cname nid nname -- 2 Turkey 1 Greece 3 Germany 1 Greece 4 Canada 5 USA 5 USA 4 Canada