mysql - 为什么这个 LEFT JOIN 消除了另一个表中没有任何内容的记录?

标签 mysql sql join left-join

我有一个 MySQL 左连接问题。

我要加入三个表。

一个人表:

CREATE TABLE person (
    id INT NOT NULL AUTO_INCREMENT,
    type ENUM('student', 'staff', 'guardian') NOT NULL,
    first_name CHAR(30) NOT NULL,
    last_name CHAR(30) NOT NULL,
    gender ENUM('m', 'f') NOT NULL,
    dob VARCHAR(30) NOT NULL,
    PRIMARY KEY (id)
);

一个学生表:

CREATE TABLE student (
    id INT NOT NULL AUTO_INCREMENT,
    person_id INT NOT NULL,
    primary_guardian INT NOT NULL,
    secondary_guardian INT,
    join_date VARCHAR(30) NOT NULL,  
    status ENUM('current', 'graduated', 'expelled', 'other') NOT NULL,
    tutor_group VARCHAR(30) NOT NULL,
    year_group VARCHAR(30) NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (person_id) REFERENCES person(id) ON DELETE CASCADE,
    FOREIGN KEY (primary_guardian) REFERENCES guardian(id),
    FOREIGN KEY (secondary_guardian) REFERENCES guardian(id),
    FOREIGN KEY (tutor_group) REFERENCES tutor_group(name),
    FOREIGN KEY (year_group) REFERENCES year_group(name)
);

还有一个事件表:

CREATE TABLE incident (
    id INT NOT NULL AUTO_INCREMENT,
    student INT NOT NULL,
    staff INT NOT NULL,
    guardian INT NOT NULL,
    sent_home BOOLEAN NOT NULL,
    illness_type VARCHAR(255) NOT NULL,
    action_taken VARCHAR(255) NOT NULL,
    incident_date DATETIME NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (student) REFERENCES student(id),
    FOREIGN KEY (staff) REFERENCES staff(id),
    FOREIGN KEY (guardian) REFERENCES guardian(id)
);

我要选择的是第 9 年每个学生的名字、姓氏和事件数。

这是我对查询的最佳尝试:

SELECT p.first_name, p.last_name, COUNT(i.student)
FROM person p, student s  LEFT JOIN incident i ON s.id = i.student 
WHERE p.id = s.person_id AND s.year_group LIKE "%Year 9%";

但是,它会忽略所有没有发生事故的学生,这不是我想要的 - 他们应该显示但计数为 0。如果我删除左连接和计数,那么我会得到所有学生,这不是我想要的。

我可能误解了 left join 但我认为它应该做的,本质上是我想做的?

谢谢你的帮助,

亚当

最佳答案

你做的很好,你只是错过了 group by 子句

SELECT p.first_name, p.last_name, COUNT(i.student)
FROM person p, student s  LEFT JOIN incident i ON s.id = i.student 
WHERE p.id = s.person_id AND s.year_group LIKE "%Year 9%"
GROUP BY p.first_name, p.last_name;

这里是一些测试数据

insert into person values(1, 'student', 'Alice', 'Foo', 'f','1970-01-01');
insert into person values(2, 'student', 'Bob', 'Bar', 'm','1970-01-01');

insert into student values(1,1,0,0,'', 'current','','Year 9');
insert into student values(2,2,0,0,'', 'current','','Year 9');

insert into incident values(1,1,0,0,0,'flu','chicken soup', '2008-01-08');

下面是添加了组 by 的查询输出:

+------------+-----------+------------------+
| first_name | last_name | COUNT(i.student) |
+------------+-----------+------------------+
| Alice      | Foo       |                1 |
| Bob        | Bar       |                0 |
+------------+-----------+------------------+

您可以通过从 where 子句中创建连接子句并根据人员 ID 进行分组来进一步清理查询:

SELECT p.first_name, p.last_name, COUNT(i.student)
FROM person p
INNER JOIN student s ON(p.id = s.person_id)
LEFT JOIN incident i ON(s.id = i.student)
WHERE s.year_group LIKE "%Year 9%"
GROUP BY p.id;

关于mysql - 为什么这个 LEFT JOIN 消除了另一个表中没有任何内容的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/424092/

相关文章:

php - 如果搜索结果不存在则隐藏表

c# - 存储过程和 SqlCommand 超时

sql - Hive 中的分层抽样

php - Mysql - 连接2个带有限制的查询

mysql - SQL:完全外部连接不工作

php - 循环进入 PHP 数组,然后循环进入 SQL 插入...或其他不同的方式...请帮忙

mysql - 如何向用户生成的 SQL 查询添加 LIMIT

mysql匹配选择像主题标签,没有全文

MYSQL - 返回一个 SELECT 减去另一个 SELECT 的结果

mySQL:左连接,需要对不同类型的数据进行连接