Запросы соединения не работают должным образом при попытке сравнить результат подсчета со значением

Я изучаю SQL по книге и пытаюсь выполнять некоторые упражнения на join queries. Единственная проблема, с которой я сталкиваюсь, заключается в том, что все мои соединения queries не работают, хотя они кажутся хорошими.

students(student_id,student_names,student_age)
courses_students(course_id,student_id)
courses(course_id,course_schedule,course_room,teacher_id)
teachers(teacher_id,teacher_names)

Запрос: «На какие курсы зачислено более 5 студентов?»

Вот что я сделал:

SELECT course_name,
       count
  (SELECT count(*)
   FROM courses) AS COUNT
FROM students,
     courses,
     courses_students
WHERE students.student_id=courses_students.student_id,
      courses.course_id=courses_students.course_id
  AND COUNT > 5

И другой - как зовут студентов, зачисленных как минимум на 2 курса, запланированных на те же часы.

Мой запрос:

SELECT student_name,
       schedule
FROM students,
     courses,
     courses_students
WHERE students.student_id=courses_students.student_id,
      courses.course_id=courses_students.course_id
  AND COUNT > 2

каков ваш ожидаемый результат?

Fahmi 29.01.2019 08:30

Для первого запроса укажите имена курсов, на которых зарегистрировано более 5 студентов, а для второго запроса — имена студентов, которые зачислены как минимум на 2 курса с одинаковым расписанием.

Christian Lisangola 29.01.2019 08:35

Совет сегодняшнего дня: переключитесь на современный явный синтаксис JOIN. Легче писать (без ошибок), легче читать (и поддерживать) и проще преобразовать во внешнее соединение, если это необходимо.

jarlh 29.01.2019 08:35
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
3
54
4

Ответы 4

В этом внутреннем запросе:

(SELECT count(*)
  FROM courses) AS COUNT

вам нужно сузить список того, что включено в COUNT. Как бы то ни было, он выбирает все элементы в таблице courses. Внутренний запрос не знает об ограничениях внешнего запроса. Попробуйте добавить предложение where в этот внутренний запрос. Возможно, вам потребуется добавить псевдонимы таблиц, чтобы однозначно ссылаться на правильную таблицу courses, чтобы не было двусмысленности, относится ли это к таблице courses во внутреннем запросе или во внешнем запросе.

И, как отмечалось в других ответах, это не лучший способ структурировать соединения.

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

      SELECT cs.course_id
        FROM courses_students cs
  INNER JOIN students s
          ON cs.course_id = s.course_id
    GROUP BY cs.course_id
      HAVING count(*) > 5

Прочтите о пунктах GROUP BY и HAVING — хороший способ решить некоторые проблемы.

Вопрос номер 2 можно решить так:

      SELECT student_names
        FROM students s 
  INNER JOIN courses_students cs
          ON cs.student_id = s.student_id
  INNER JOIN (    
              SELECT course_id
                FROM courses c
            GROUP BY course_schedule
              HAVING count(*) > 1
             ) sub
             ON sub.course_id = cs.course_id

INNER JOIN с подзапросом выбирает курсы, запланированные на одно и то же время (имеющие один и тот же курс_расписания). Поскольку другие таблицы «подключены» к INNER JOIN, у нас, наконец, будет просто подмножество студентов, которые участвуют в одном из этих курсов.

В MySQL вам необходимо явно определить joins. В отличие от Oracle, он не может обрабатывать соединения со знаком =.

SELECT course_name,
       count
  (SELECT count(*)
   FROM courses) AS COUNT
FROM students 
     INNER JOIN courses  on courses.course_id=courses_students.course_id
     INNER JOIN courses_students  on students.student_id=courses_students.student_id
WHERE  COUNT(*) > 2

Вам нужно агрегировать по курсу, а затем указать количество студентов:

SELECT
    c.course_name,
    COUNT(*) AS cnt
FROM courses c
INNER JOIN courses_students cs
    ON c.course_id = cs.course_id
INNER JOIN students s
    ON cs.student_id = s.student_id
GROUP BY
    c.course_name
HAVING
    COUNT(*) > 5;

Другие вопросы по теме