我们假设我只能在SQLite中执行此操作。
我有两张桌子。
State {
DistrictID: int
SubdistrictID: int
CityID: Int
name: varchar(36)
}
在州表中显然是一个明显的层次结构。一个州有多个区,每个区都有一些分区,每个分区都有一些城市。
另一张表是一个城市的学生人数,其中Students.CityID = State.CityID
Students {
CityID: int
number: int
}
我想知道一个区内现有的学生人数' 221'
QUERY :SELECT sum(students.number) from State LEFT JOIN Students students ON State.CityID = students.CityID WHERE State.DistrictID = 221 GROUP BY State.DistrictID
到目前为止,这确实有效。我得到了来自221区所有城市的学生总数。
某些城市在子区域之间共享。在这种情况下,一个区有一个城市在两个分区之间共享。这反映在州表中。
State Table
Row0: DistrictID: 221; SubDistrictID: 332; CityID: 554
Row1: DistrictID: 221; SubDistrictID: 332; CityID: 555
Row2: DistrictID: 221; SubDistrictID: 333; CityID: 554
Row3: DistrictID: 221; SubDistrictID: 333; CityID: 557
第0行和第2行在两个分区(332和333)之间共享同一个城市(554)。
在这种情况下,上面的sql查询会将SUM()值加倍,因为同一城市的数量是TWICE。
如何通过不改变表的架构来解决由于技术错误但却是现实问题而在逻辑上出现的复杂复制?我尝试使用distinct
,但它并不适合这个目的,因此不起作用。
答案 0 :(得分:1)
在执行select distinct
之前,您可以使用join
获取区内每个城市的一个引用:
select sum(s.number)
from (select distinct cityid
from state
where destrictid = 21
) c left join
students s
on s.cityid = c.cityid
答案 1 :(得分:0)
Sum
会添加所有Student.Numbers
。如果您想要学生人数,请使用count
。为了给你一个想法,如果该区有2名学生,其中一名学生Student.number
1而另一名学生Student.Number
4,sum
将返回5,count
将返回2:
select sum(S.number)
from Students S inner join State St on S.CityId = St.CityId
where St.DistrictID = 221
由于您正在寻找单个DistrictId
,因此您不需要group by districtId
。此外,我使用的是inner join
,因为您只希望CityId
表中有State
的学生。
编辑:
您可以按如下方式加入其他表:
select D.DistrictName, sum(S.number)
from Students S inner join State St on S.CityId = St.CityId
inner join City C on St.CityId = C.Id
inner join District D on St.DistrictId = D.DistrictId
where St.DistrictID = 221
group by D.DistrictName