LEFT JOIN путаница - мне нужно получить количество студентов - PullRequest
1 голос
/ 22 января 2011

У меня есть четыре таблицы:

students
classes
teachers
teacher_assignments

classes и teachers имеет отношение многие ко многим, поэтому teacher_assignments действует как таблица xref (с полями teacher_idи class_id).

У каждого учащегося в students есть class_id (много к одному - много учеников в одном классе).

Я должен такжеотметим, что teacher_assignments имеет столбец active (BOOL), который указывает, активно ли это назначение


Что я хочу сделать:

Я хочу получитьследующее:

  • class_name - конкат его уровня и подуровня, например, 3 и A
  • teacher_names - имена учителей в настоящее времяназначенный этому классу
  • student_count - количество учеников в каждом классе

Сначала я попытался получить только class_name и teacher_names, вот так:

SELECT
    CONCAT(CONVERT(classes.level, CHAR(8)), classes.sub_level) AS class_name,
    GROUP_CONCAT(DISTINCT teachers.name SEPARATOR ',') AS teacher_names

FROM
    teacher_assignments
        LEFT JOIN teachers
            ON teachers.id = teacher_assignments.teacher_id
            AND teacher_assignments.active = TRUE
        LEFT JOIN classes
            ON classes.id = teacher_assignments.class_id

GROUP BY classes.id

Работает нормально и выводит:

 class_name | teacher_names
 --------------------------------------
 1A         | NULL
 2A         | John, Sam
 3B         | Sam, Sarah

(в классе 1A в настоящее время нет учителей, поэтому ожидается NULL)

... НО , теперь я понятия не имею, какork student_count в это.


Мой вопрос:

Как именно таблица students должна быть соединена с другими в приведенном выше запросе, чтобы я мог получить student_count колонка?

Ответы [ 3 ]

2 голосов
/ 22 января 2011

Использование:

   SELECT CONCAT(CONVERT(c.level, CHAR(8)), c.sub_level) AS class_name,
          GROUP_CONCAT(DISTINCT teachers.name SEPARATOR ',') AS teacher_names,
          COUNT(s.id) AS studentCount
     FROM CLASSES c
LEFT JOIN TEACHER_ASSIGNMENTS ta ON ta.class_id = c.id
                                AND ta.active = TRUE
LEFT JOIN TEACHERS t ON t.id = ta.teacher_id
LEFT JOIN STUDENTS s ON s.class_id = c.id
 GROUP BY class_name

На псевдонимы столбцов можно ссылаться в GROUP BY при использовании MySQL, в противном случае вам придется дублировать логику, которая создает значение столбца class_name. Это также столбец для GROUP, поскольку GROUP_CONCAT и COUNT являются агрегатными функциями.

Чтобы получить ноль в качестве значения счетчика, вам может понадобиться:

   SELECT CONCAT(CONVERT(c.level, CHAR(8)), c.sub_level) AS class_name,
          GROUP_CONCAT(DISTINCT teachers.name SEPARATOR ',') AS teacher_names,
          COALESCE(COUNT(s.id), 0) AS studentCount
     FROM CLASSES c
LEFT JOIN TEACHER_ASSIGNMENTS ta ON ta.class_id = c.id
                                AND ta.active = TRUE
LEFT JOIN TEACHERS t ON t.id = ta.teacher_id
LEFT JOIN STUDENTS s ON s.class_id = c.id
 GROUP BY class_name
1 голос
/ 22 января 2011

Подумав головой ...

  1. Присоединяйтесь к classes и students таблицам, чтобы получить количество студентов ...
  2. Вместо того, чтобылевое соединение в classes в указанном выше запросе, вы будете выполнять левое соединение с результатом # 1 (по сути, внутреннее соединение между таблицами classes и students), которое позволит вам получить количество студентов.
0 голосов
/ 22 января 2011

Я не думаю, что использовал бы объединение, но вместо этого использовал бы встроенный столбец выбора для студента, как это:

SELECT
  CONCAT(CONVERT(classes.level, CHAR(8)), classes.sub_level) AS class_name,
  GROUP_CONCAT(DISTINCT teachers.name SEPARATOR ',') AS teacher_names,
  ( SELECT COUNT(*) FROM students WHERE students.class_id = classes.id ) AS student_count
FROM ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...