显示所有组并计算给定组中的项目(包括 0 个结果)

问题描述 投票:0回答:1

我有两张桌子:

class
student
。我想获取所有现有班级并获取每个给定班级的学生人数(计数)。技巧是我还想显示一个有
0
学生的班级。

表“”:

DROP TABLE IF EXISTS "class";
CREATE TABLE class(
  class_id SERIAL PRIMARY KEY,
  class_name VARCHAR
);


INSERT INTO class (class_name) VALUES ('A');
INSERT INTO class (class_name) VALUES ('B');
INSERT INTO class (class_name) VALUES ('C');

表“学生”:

DROP TABLE IF EXISTS "student";
CREATE TABLE student(
  student_id SERIAL PRIMARY KEY,
  student_name VARCHAR,
  class_id numeric
);

INSERT INTO student (student_name, class_id) VALUES ('Mike', 1);
INSERT INTO student (student_name, class_id) VALUES ('Jessica', 1);
INSERT INTO student (student_name, class_id) VALUES ('Thomas', 1);

INSERT INTO student (student_name, class_id) VALUES ('Jacob', 2);
INSERT INTO student (student_name, class_id) VALUES ('Izabella', 2);

我的查询有效,但

NOT
是否显示班级
C 
0
学生:

SELECT class_name, student.class_id, COUNT(DISTINCT student_id) AS num_students
FROM student
LEFT JOIN class ON student.class_id = class.class_id
GROUP BY student.class_id, class.class_name;

以上查询给出了以下结果:

类名 class_id num_学生
A 1 3
B 2 2

我希望能够得到这样的东西:

类名 class_id num_学生
A 1 3
B 2 2
C 3 0
sql postgresql group-by left-join
1个回答
1
投票

从描述来看,您的查询似乎旨在回答“对于每个班级,有多少名独特的学生注册?”的问题。不幸的是,您编写的查询回答了一个略有不同的问题;即“对于每个至少有一名注册学生的班级,注册了多少名独特的学生?”

为了可读性/清晰度,我建议将

class
放在
FROM
子句中,因为它是驱动表。对于包含多个表的查询,请始终限定列名称,以便轻松识别源,而无需引用每个表的 DDL。在选择列表中,仅在必要时引用外部连接表中的列,因为如果不满足连接条件,它们将是
NULL

以下查询产生请求的结果:

SELECT class.class_name, class.class_id, COUNT(DISTINCT student.student_id) AS num_students
  FROM class
  LEFT JOIN student
    ON class.class_id = student.class_id
  GROUP BY class.class_id
  ORDER BY class.class_name;

请注意,此查询仅按

class.class_id
分组。由于
class_id
是主键,因此在分组表达式列表中包含
class
中的其他列是多余的,因为每个列都完全依赖于
class_id

student(class_id)
引用
class(class_id)
应该有外键约束。

© www.soinside.com 2019 - 2024. All rights reserved.