使用联接获取多个表的数据计数

时间:2019-01-31 09:46:19

标签: sql sql-server join

我有下表:

    1. school
       - id
       - name
    2. grade
       - id
       - name
       -school_id
    3. class
       - id
       - name
       - grade_id
   4. student
       - id
       - name
       - class_id
   5. donation
       - id
       - amount
       - student_id

我想获得每所学校的年级,班级,学生,捐赠号 我已经尝试过该查询

    SELECT school.id AS ID, school.name AS Name,COUNT(student.id) AS 
    Students,COUNT(class.id) AS Class,COUNT(grade.id) AS Grade
    FROM (((
    INNER JOIN class ON student.classId=class.id )
    INNER JOIN grade ON class.gradeId=grade.id)
    INNER JOIN school ON grade.sclId=school.id)
    GROUP BY ID;

,但返回错误结果。花足够的时间来解决这个问题,但没有得到任何解决方案。有谁可以帮忙?

3 个答案:

答案 0 :(得分:0)

您可以尝试以下不带括号的查询。并且您还需要在non-aggregated列表中包括sc.namegroup by。顺便说一下,即使学生的其他三个表中至少有一个表的数据不匹配,也要考虑使用LEFT JOIN

SELECT sc.id AS ID,
       sc.name AS Name,
       COUNT(st.id) AS Students,
       COUNT(c.id) AS Class,
       COUNT(g.id) AS Grade
  FROM student s
  LEFT JOIN class c ON c.id = s.classId 
  LEFT JOIN grade g ON g.id = c.gradeId
  LEFT JOIN school sc ON sc.id = g.sclId
 GROUP BY sc.id, sc.name;

答案 1 :(得分:0)

您可以尝试以下查询

SELECT sc.Id, sc.Name
    , SUM(CASE WHEN g.Id IS NOT NULL THEN 1 ELSE 0 END ) AS Grade
    , SUM(CASE WHEN c.Id IS NOT NULL THEN 1 ELSE 0 END ) AS Class
    , SUM(CASE WHEN s.Id IS NOT NULL THEN 1 ELSE 0 END ) AS Students
FROM School AS sc
    LEFT OUTER JOIN Grade AS g ON sc.Id = g.sclId
    LEFT OUTER JOIN Class AS c ON g.Id = c.GradeId
    LEFT OUTER JOIN Student AS s ON c.Id = s.classId
GROUP BY sc.Id, sc.Name

答案 2 :(得分:0)

您的连接具有多个维度,因此行数乘以连接数。有两种处理计数的方法。更“正确”的方法是在进行联接之前进行聚合。

第二种方法更简单,所以我建议使用COUNT(DISTINCT)

SELECT sc.id AS ID, sc.name AS Name,
       COUNT(DISTINCT s.id) AS num_Students,
       COUNT(DISTINCT c.id) AS num_Classes,
       COUNT(DISTINCT g.id) AS num_Grades
FROM student s INNER JOIN
     class c
     ON s.classId = c.id INNER JOIN
     grade g
     ON c.gradeId = g.id INNER JOIN
     school sc
     ON g.sclId = s.id
GROUP BY sc.id, sc.name;

注意:

  • “真实” SQL数据库中的连接不需要括号。
  • 您应该按所有未聚合的列进行聚合(包括nameid)。
  • 强烈建议使用表别名。