3

MySQL の左結合の問題があります。

参加しようとしているテーブルが 3 つあります。

人物表:

CREATE TABLE 人 (
    ID INT NOT NULL AUTO_INCREMENT、
    type ENUM('生徒', 'スタッフ', '保護者') NOT NULL,
    first_name CHAR(30) NOT NULL、
    last_name CHAR(30) NOT NULL、
    性別 ENUM('m', 'f') NOT NULL,
    dob VARCHAR(30) NOT NULL,
    主キー (ID)
);

学生テーブル:

CREATE TABLE 学生 (
    ID INT NOT NULL AUTO_INCREMENT、
    person_id INT NOT NULL、
    primary_guardian INT NOT NULL,
    セカンダリ ガーディアン INT、
    join_date VARCHAR(30) NOT NULL、  
    status ENUM('current', '卒業', '追放', 'other') NOT NULL,
    tutor_group VARCHAR(30) NOT NULL,
    year_group VARCHAR(30) NOT NULL、
    主キー (ID)、
    FOREIGN KEY (person_id) REFERENCES person(id) ON DELETE CASCADE,
    FOREIGN KEY (primary_guardian) REFERENCES ガーディアン(id),
    FOREIGN KEY (secondary_guardian) REFERENCES ガーディアン(id),
    FOREIGN KEY (tutor_group) REFERENCES tutor_group(name),
    FOREIGN KEY (year_group) REFERENCES year_group(名前)
);

インシデント テーブル:

CREATE TABLE インシデント (
    ID INT NOT NULL AUTO_INCREMENT、
    学生INT NOT NULL、
    スタッフINT NOT NULL、
    ガーディアンINT NOT NULL、
    sent_home BOOLEAN NOT NULL,
    disease_type VARCHAR(255) NOT NULL,
    action_taken VARCHAR(255) NOT NULL,
    インシデント_日付DATETIME NOT NULL、
    主キー (ID)、
    FOREIGN KEY (学生) REFERENCES 学生(ID),
    FOREIGN KEY (staff) REFERENCES staff(id),
    FOREIGN KEY (ガーディアン) REFERENCES ガーディアン(id)
);

私が選択しようとしているのは、9 年生の各生徒の名、姓、およびインシデントの数です。

クエリでの私の最善の試みは次のとおりです。

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

しかし、それは私が望むものではないインシデントのない学生を無視します - それらは表示されるべきですが、カウントは 0 です。

私はおそらく左結合を誤解していましたが、本質的に私がやろうとしていることは何だと思いましたか?

ご協力いただきありがとうございます、

アダム

4

4 に答える 4

6

あなたがやっていることは問題ありません.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;
于 2009-01-08T13:10:15.540 に答える
0

それはあなたが探している左外部結合ではありませんか? 用語が混同されている可能性がありますか?初めてではないでしょう。しかし、アロンの答えはうまくいくでしょう。

于 2009-01-08T12:51:44.437 に答える
0

または、相関サブクエリLEFT JOINを使用して回避できます。

SELECT
  p.first_name
  , p.last_name
  , (SELECT COUNT(*) FROM incident i WHERE i.student = s.id) 
FROM
  person p JOIN student s on s.person_id = p.id
WHERE
  s.year_group LIKE "%Year 9%"
于 2009-01-08T12:56:43.117 に答える
0

最初は group by なしで count を使用しており、結合に「where」構文と「on」構文を混在させています。これを試して:

SELECT p.first_name, p.last_name, COUNT(i.student)
FROM person p
JOIN student s on p.id = s.person
LEFT JOIN incident i ON s.id = i.student 
WHERE s.year_group LIKE "%Year 9%"
GROUP BY P.id;
于 2009-01-08T13:14:22.097 に答える