【问题标题】:How to I find the person who has taught the most classes如何找到教过最多课程的人
【发布时间】:2021-02-12 11:26:52
【问题描述】:

我想尝试找到教过最多课程的员工作为职位Teacher。所以在这里我想打印出Nick,因为他以Teacher 的身份教过最多的课程。

但是,我得到了错误:

错误:列“e.name”必须出现在 GROUP BY 子句中或用于聚合函数位置:24

CREATE TABLE employees (
  id integer primary key,
  name text
);

CREATE TABLE positions (
  id integer primary key,
  name text
);

CREATE TABLE teaches (
  id integer primary key,
  class text,
  employee integer,
  position integer,
  foreign key (employee) references employees(id),
  foreign key (position) references positions(id)
);

INSERT INTO employees (id, name) VALUES
(1, 'Clive'), (2, 'Johnny'), (3, 'Sam'), (4, 'Nick');

INSERT INTO positions (id, name) VALUES
(1, 'Assistant'), (2, 'Teacher'), (3, 'CEO'), (4, 'Manager');

INSERT INTO teaches (id, class, employee, position) VALUES
(1, 'Dancing', 1, 1), (2, 'Gardening', 1, 2),
(3, 'Dancing', 1, 2), (4, 'Baking', 4, 2),
(5, 'Gardening', 4, 2), (6, 'Gardening', 4, 2),
(7, 'Baseball', 4, 1), (8, 'Baseball', 2, 1),
(9, 'Baseball', 4, 2);

我正在尝试使用的 SQL 语句:

SELECT count(t.class), e.name
FROM positions p
JOIN teaches t
ON p.id = t.position
JOIN employees e
ON e.id = t.employee
WHERE p.name = 'Teacher'
GROUP BY t.employee;

我一直在用 sql fiddle 做这个: http://www.sqlfiddle.com/#!17/a8e19c/3

【问题讨论】:

    标签: sql postgresql count sql-order-by inner-join


    【解决方案1】:

    您的查询看起来不错。您只需修复GROUP BY 子句,使其与SELECT 子句中的列一致。然后ORDER BYLIMIT

    SELECT count(*) cnt_classes, e.name
    FROM positions p 
    INNER JOIN teaches   t ON p.id = t.position
    INNER JOIN employees e ON e.id = t.employee
    WHERE p.name = 'Teacher' 
    GROUP BY e.id              --> primary key of "employees"
    ORDER BY cnt_classes DESC  --> order by descending count of classes
    LIMIT 1                    --> keep the first row only
    

    【讨论】:

    • 我想你的意思是 GROUP BY e.name
    • @mister_smythers:我的意思是e.id。那就是employee表的PK,name函数依赖id
    • 你是对的。我不知道为什么我不能在我的数据库中以 Teachers.id 作为主要列来做到这一点。似乎是同一个查询。 select count(*) sec_count, teachers.teacher_number from teachers inner join sections on teachers.id = sections.teacher inner join schools on teachers.school = schools.id group by teachers.id order by sec_count desc 只有当teachers.teacher_number 在我的数据库中是唯一的时,此代码才有效?然后只有在您发布的回复中 e.name 是唯一的时它才会起作用?
    【解决方案2】:

    在您的选择中,您正在使用聚合 COUNT 计算每个组中的所有行 (GROUP BY t.employee),但您不聚合 e.name

    因此,对于 Nick,您基本上为一个有两列的班级选择 4 行 - 班级名称和教师姓名。然后,您要求服务器计算 Nicks 组中的班级名称(通过他的员工 ID),将 4 行聚合为值为 4 的行,但您对教师姓名不做任何事情,因此您的结构无效,其中您有 1 行班级计数列和教师姓名的 4 行。其他老师也一样。这就是服务器所抱怨的。解决这个问题的最简单方法是将 e.name 添加到 GROUP BY,这会将这 4 行相同值的行合并为一行。

    要获得教授大多数课程的老师,您只需按课程数量降序对结果进行排序,并将结果数量限制为 1。这将为您提供课程数量最多的结果行。

    更新小提琴:http://www.sqlfiddle.com/#!17/a8e19c/7

    【讨论】:

      【解决方案3】:

      您收到错误是因为您需要拥有您选择的每一列(例如,本示例中的 GROUP BY 子句中的名称,否则 SQL 不知道如何分组并返回一个计数列。如果您想返回最多的人,您还需要使用 TOP(1) 和 order by。

      SELECT TOP(1) count(*), e.name
      FROM teaches t 
      INNER JOIN positions p ON t.position = p.id
      INNER JOIN employees e ON e.id = t.employee
      WHERE p.name = 'Teacher'
      GROUP BY e.name
      ORDER BY count(*) DESC;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-11
        • 1970-01-01
        • 2020-11-11
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 2012-08-11
        相关资源
        最近更新 更多