选择在SQL中有10名以上的学生和教师的城市

时间:2018-11-17 14:06:48

标签: sql oracle

我需要显示城市,州,学生居住人数,教师居住人数以及该城市的学生/教师总数。该信息包含在3个表中:ZIPCODE,STUDENT和INSTRUCTOR。

  • ZIPCODE表具有列ZIP,CITY和STATE。
  • STUDENT表具有STUDENT_ID和ZIP。
  • INSTRUCTOR表具有INSTRUCTOR_ID和ZIP。

我尝试了几次内部联接和相交,但是我不断遇到各种各样的错误。我对SQL还是很陌生,并且不确定如何实际进行这项工作,任何帮助或建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

为此,您可能需要混合使用工会和加入。我怀疑你要相交。多种方法可以做到,这是一种

SELECT
  Z.city,
  Z.state,
  SUM(case when d.typ = 's' then 1 ELSE 0 END) as count_students,
  SUM(case when d.typ = 'i' then 1 ELSE 0 END) as count_instructors,
  Count(*) as count_all
FROM
  (SELECT * FROM
    (SELECT 's' as typ, zip FROM student)
    UNION ALL
    (SELECT 'I ' as typ, zip FROM Instructor)
  ) d
  INNER JOIN
  zipcode z
  ON d.zip on z.zip
GROUP BY 
  z.city, z.state

我从每个学生和讲师表中拉出所有记录,并将它们合并成一个大列表,创建一列以跟踪类型,总和进行计数,当类型为s时,返回时为a 1.总和将1s加起来作为计数。因此,您最终每行都有一个城市/州/类型组合,然后按城市和州分组并在类型上求和,则得出一个计数

这是另一种方法:

SELECT
  Z.city,
  Z.state,
  SUM(s.ct) as count_students,
  SUM(i.ct) as count_instructors,
  SUM(s.ct) + SUM(I.ct) as count_all
FROM
  zipcode z
  LEFT OUTER JOIN
  (SELECT zip, count(*) ct FROM student GROUP BY zip) s
  ON s.zip = z.zip

  LEFT OUTER JOIN  
  (SELECT zip, count(*) as ct FROM Instructor GROUP BY zip) i 
  ON i.zip = z.zip

GROUP BY z.city, z.state

我们将学生和讲师分组并计数在各自的子查询中,每个邮政编码仅产生一次计数,并将这些(左联接)加入所有邮政编码。我们对子查询进行分组,以确保邮政编码和s / i之间只有1:1的关系。如果为1:很多,则总和会失真。由于多个邮政编码可以指向一个城市,因此需要进行另一轮分组和汇总,以汇总一个城市的所有邮政编码