Sql 左连接和求和以及分组奇数行为
我有两张桌子:Sql 左连接和求和以及分组奇数行为,sql,sql-server,Sql,Sql Server,我有两张桌子: student attendance table - student_id, campus_section campus table - campus_section, number_of_students, campus_name 样本数据: Student Table: Student_Id, campus_section 1, ddr1 2, ddr1 3, ddr2 4, ddr3 5, ddv1 6, ddv2 7, ddv6 Campus Table Ca
student attendance table - student_id, campus_section
campus table - campus_section, number_of_students, campus_name
样本数据:
Student Table:
Student_Id, campus_section
1, ddr1
2, ddr1
3, ddr2
4, ddr3
5, ddv1
6, ddv2
7, ddv6
Campus Table
Campus_Section, Number_Of_Students, Campus_Name
ddr1, 10, ddr
ddr2, 5, ddr
ddr3, 5, ddr
ddv1, 5, ddv
ddv2, 10, ddv
ddv3, 10, ddv
ddv6, 10, ddv
因此,预期的行将是
Campus, current_students, campus_students
ddr, 4, 20
ddv, 3, 35
每个校园\u名称可以有多个校园\u节行。以下查询列出了校园名称、该校园的在校学生人数以及该校园的学生总数
select d.[campus_name] as campus_name,
cast(count(s.student_id) as int) as current_students,
sum(cast (d.[number_of_students] as int)) as campus_students
from campus d
left join student s
on s.campus_section = d.campus_section
group by d.[campus_name]
对于某些校园名称,section_students列中的结果大于此值:
select d.[campus_name] as campus_name,
sum(cast (d.[number_of_students] as int)) as section_students
from campus d
group by d.[campus_name]
这意味着left join正在做某些特定行不应该做的事情。或者第二个查询可能不正确
编辑:例如,第一个查询将为某个校园名称提供18,而第二个查询将为10
有人能解释一下发生了什么事吗?这是sql server 2008 使用左join,sumcast d.[学生人数]as int将是校园中的学生人数*学生人数。通过陈述摆脱分组,你会发现原因
select d.[campus_name] as campus_name,
s.student_id,
d.[number_of_students]
from campus d
left join student s
on s.campus_section = d.campus_section
因此,正确的方法是:
select d.[campus_name] as campus_name,
cast(count(s.student_id) as int) as current_students,
cast (d.[number_of_students] as int) as section_students
from campus d
left join student s
on s.campus_section = d.campus_section
group by d.[campus_name],cast (d.[number_of_students] as int)
更新
根据稍后发布的OP数据,需要先按校园分组以获得科室学生人数之和,然后加入学生表并按校园名称分组以获得当前科室学生人数
with campus_t as (select d.[campus_name] as campus_name,
sum(cast (d.[number_of_students] as int)) as campus_students
from campus d
group by d.[campus_name])
select d.campus_name,
d.campus_students,
cast(count(s.student_id) as int) as current_students,
from campus_t d
left join campus section
on section.campus_name = d.campus_name
left join student s
on s.campus_section = section.campus_section
group by d.campus_name,d.campus_students
注:尚未测试。请检查一下
你的问题来自非规范化设计。校园表应拆分为两个校园和校园分区表。这就是为什么我必须添加一个名为campus\u t的CTE表来获取campus实体的信息。原始校园表的数据表示校园分区实体。如果将模型规范化为三个表,那么应该更容易查询。节可以有多个学生。因此,当连接表时,校园中的行可能会重复,如果您尝试一次性聚合所有内容,则会使结果倾斜 因此,请尝试分两步进行:首先,按校园分区计算学生人数:
SELECT
campus_section,
number_of_students,
campus_name,
COUNT(s.student_id)
FROM
dbo.Campus AS c
LEFT JOIN
dbo.Student AS s
ON
c.campus_section = s.campus_section
GROUP BY
campus_section,
number_of_students,
campus_name
然后按校园汇总分区结果:
SELECT
campus_name,
current_campus = SUM(current_section),
campus_students = SUM(number_of_students)
FROM
(
SELECT
c.campus_section,
c.number_of_students,
c.campus_name,
current_section = COUNT(s.student_id)
FROM
dbo.Campus AS c
LEFT JOIN
dbo.Student AS s
ON
c.campus_section = s.campus_section
GROUP BY
campus_section,
number_of_students,
campus_name
) AS sub
GROUP BY
campus_name
;
你能告诉我们预期输出和实际输出吗?@SimonWhitehead我不应该发布任何数据,但我的问题中有几个输入错误,所以请重新阅读。谢谢。它不一定是实际数据,而是一个非常小的模拟样本数据。@SimonWhitehead请查看编辑。我对我的第一个查询做了一点编辑,将“大学学生”部分替换为“校园学生”。sumcast d.[大学学生人数]与校园学生人数相同,应代表该校园而非该部分的学生总数。您的方法将为每个校园名称提供多行,但我只希望每个校园有一行。我已经发布了示例数据和预期结果。