학생 수강 분석을 위한 SQL 쿼리

SQLBeginner
지금 연습하기

소개

이 프로젝트에서는 학생 - 강좌 데이터베이스에 대해 다양한 SQL 쿼리를 수행하는 방법을 배우게 됩니다. 데이터베이스는 세 개의 테이블로 구성됩니다: 학생 테이블 (S), 강좌 테이블 (C), 그리고 학생 - 강좌 테이블 (SC). 이러한 테이블에서 데이터를 검색하고 조작하여 다양한 작업을 수행하는 방법을 배우게 됩니다.

👀 미리보기

SQL database preview image

🎯 과제

이 프로젝트에서 다음을 배우게 됩니다:

  • "Daniel" 강사가 가르치는 강좌를 수강하지 않은 모든 학생의 이름을 나열하는 방법
  • 두 개 이상의 강좌에서 낙제 (성적 < 60) 한 학생의 학번과 이름을 나열하는 방법
  • 강좌 "11"과 강좌 "12"를 모두 수강한 모든 학생의 이름을 나열하는 방법
  • 강좌 "11"의 성적이 강좌 "12"보다 높은 모든 학생의 학번을 나열하고 오름차순으로 정렬하는 방법
  • "John Davis"보다 나이가 많은 모든 학생의 이름을 나열하는 방법
  • 강좌 "12"를 수강한 모든 학생 중 가장 높은 성적을 받은 학생의 학번을 나열하는 방법
  • 모든 학생의 이름과 선택한 강좌 ID 및 성적을 함께 나열하는 방법
  • 네 개 이상의 강좌를 수강한 학생의 학번과 총 성적 (별칭: SG) 을 총 성적의 내림차순으로 정렬하여 나열하는 방법

🏆 성과

이 프로젝트를 완료하면 다음을 수행할 수 있습니다:

  • 관계형 데이터베이스에서 데이터를 검색하고 조작하기 위해 복잡한 SQL 쿼리를 작성하는 방법을 이해합니다.
  • 서브쿼리 (subqueries), 조인 (joins), 집계 (aggregations), 정렬 (sorting) 과 같은 다양한 SQL 기술을 적용하여 실제 데이터 분석 문제를 해결합니다.
  • 데이터 기반 의사 결정 및 문제 해결에 필수적인 SQL 기술을 개발합니다.

MySQL 시작 및 데이터 가져오기

이 단계에서는 MySQL 서비스를 시작하고 필요한 데이터를 데이터베이스로 가져오는 방법을 배우게 됩니다.

  1. sudo 명령을 사용하여 비밀번호 없이 MySQL 서비스를 시작합니다:
sudo service mysql start
  1. sudo 명령을 사용하여 비밀번호 없이 MySQL 클라이언트에 접속합니다:
sudo mysql
  1. 제공된 personnel.sql 스크립트에서 데이터를 MySQL 데이터베이스로 가져옵니다:
SOURCE /home/labex/project/initdb.sql
✨ 솔루션 확인 및 연습

쿼리 코드 추가

이 단계에서는 "Daniel" 강사가 가르치는 강좌를 수강하지 않은 모든 학생의 이름을 나열하는 방법을 배우게 됩니다. 이 단계를 완료하려면 아래 단계를 따르세요:

  1. /home/labex/project 디렉토리에서 answer.sql 파일을 엽니다.

  2. 주석 아래에 SQL 문을 추가합니다.

  3. 주석 -- List the names of all students who have not taken courses taught by the "Daniel" teacher.를 찾습니다.

    SELECT s.sname
    FROM S s
    WHERE NOT EXISTS (
      SELECT 1
      FROM SC sc
      JOIN C c ON sc.cno = c.cno
      WHERE c.tname = 'Daniel' AND sc.sno = s.sno
    );

    이 SQL 문은 먼저 S 테이블에서 sname 열을 선택합니다. 그런 다음 NOT EXISTS 절을 사용하여 "Daniel" 강사가 가르치는 강좌와 일치하는 강좌 ID (cno) 를 가진 레코드가 SC 테이블에 있는지, 그리고 학생 ID (sno) 가 현재 학생과 일치하는지 확인합니다. 그러한 레코드가 없으면 학생의 이름이 결과에 포함됩니다.

  4. 주석 -- List the student numbers and names of students who have failed (grade < 60) in two or more courses.를 찾습니다.

    SELECT s.sno, s.sname
    FROM S s
    JOIN SC sc ON s.sno = sc.sno
    WHERE sc.grade < 60
    GROUP BY s.sno, s.sname
    HAVING COUNT(sc.sno) >= 2;

    이 SQL 문은 먼저 S 테이블과 SC 테이블을 조인하여 학생 정보와 강좌 성적을 가져옵니다. 그런 다음 성적이 60 미만인 레코드를 필터링하고, 학생 번호와 이름으로 결과를 그룹화한 다음, HAVING 절을 사용하여 두 개 이상의 강좌에서 낙제한 학생만 선택합니다.

  5. 주석 -- List the names of all students who have taken both course "11" and course "12".를 찾습니다.

     SELECT s.sname
     FROM S s
     JOIN SC sc ON s.sno = sc.sno
     WHERE sc.cno IN (11, 12)
     GROUP BY s.sno
     HAVING COUNT(DISTINCT sc.cno) = 2
     ORDER BY s.sno;

    이 SQL 문은 먼저 S 테이블과 SC 테이블을 조인하여 학생 정보와 강좌 ID 를 가져옵니다. 그런 다음 강좌 ID 가 11 또는 12 인 레코드를 필터링하고, 학생 번호로 결과를 그룹화한 다음, HAVING 절을 사용하여 두 강좌를 모두 수강한 학생만 선택합니다. 마지막으로 학생 번호로 결과를 정렬합니다.

  6. 주석 -- List the student numbers of all students whose grades in course "11" are higher than those in course "12", and sort them in ascending order.를 찾습니다.

    SELECT sc11.sno
    FROM SC sc11
    JOIN SC sc12 ON sc11.sno = sc12.sno AND sc12.cno = 12
    WHERE sc11.cno = 11 AND sc11.grade > sc12.grade
    ORDER BY sc11.sno;

    이 SQL 문은 먼저 SC 테이블을 자체적으로 조인하여 강좌 11 과 강좌 12 의 성적 정보를 가져옵니다. 그런 다음 강좌 ID 가 11 이고 성적이 강좌 12 의 성적보다 높은 레코드를 필터링하고 학생 번호를 선택합니다. 마지막으로 학생 번호로 결과를 정렬합니다.

  7. 주석 -- List the names of all students who are older than "John Davis".를 찾습니다.

    SELECT s.sname
    FROM S s, (SELECT sage FROM S WHERE sname = 'John Davis') AS zs
    WHERE s.sage > zs.sage;

    이 SQL 문은 먼저 "John Davis"라는 이름을 가진 학생의 sage 값을 선택하여 서브쿼리 zs에 저장합니다. 그런 다음 학생의 나이 (sage) 가 "John Davis"의 나이보다 큰 S 테이블에서 sname을 선택합니다.

  8. 주석 -- List the student number of the student with the highest grade among all students who have taken course "12".를 찾습니다.

    SELECT sc.sno
    FROM SC sc
    WHERE sc.cno = 12 AND sc.grade = (
      SELECT MAX(grade)
      FROM SC
      WHERE cno = 12
    );

    이 SQL 문은 먼저 강좌 ID 가 12 이고 성적이 강좌 12 를 수강한 모든 학생 중 최대 성적과 같은 SC 테이블에서 sno를 선택합니다. 이렇게 하면 강좌 12 에서 가장 높은 성적을 받은 학생의 학번을 얻을 수 있습니다.

  9. 주석 -- List the names of all students, along with their selected course IDs and grades.를 찾습니다.

    SELECT s.sname, sc.cno, sc.grade
    FROM S s
    LEFT JOIN SC sc ON s.sno = sc.sno;

    이 SQL 문은 S 테이블과 SC 테이블 간에 왼쪽 조인 (left join) 을 수행합니다. 이는 SC 테이블에 레코드가 없는 경우에도 S 테이블의 모든 학생을 포함합니다. 이렇게 하면 모든 학생 이름과 함께 강좌 ID 및 성적 (있는 경우) 이 결과에 포함됩니다.

  10. 주석 -- List the student numbers and total grades (alias as: SG) of students who have taken four or more courses, sorted in descending order of total grades.를 찾습니다.

    SELECT sc.sno, SUM(sc.grade) AS SG
    FROM SC sc
    GROUP BY sc.sno
    HAVING COUNT(sc.cno) >= 4
    ORDER BY SG DESC;

    이 SQL 문은 먼저 SC 테이블을 학생 번호 (sno) 로 그룹화하고 각 학생의 성적 합계를 계산합니다 (별칭 SG). 그런 다음 HAVING 절을 사용하여 네 개 이상의 강좌를 수강한 학생만 포함하도록 결과를 필터링합니다. 마지막으로 총 성적의 내림차순으로 결과를 정렬합니다.

✨ 솔루션 확인 및 연습

SQL 스크립트 실행

이 마지막 단계에서는 이전 단계에서 생성한 SQL 스크립트를 실행합니다.

  1. MySQL 클라이언트에서 다음 명령을 실행하여 answer.sql 스크립트를 실행합니다:
SOURCE /home/labex/project/answer.sql

이렇게 하면 answer.sql 파일의 SQL 쿼리가 실행되고 결과가 표시됩니다.

축하합니다! 프로젝트를 완료했습니다. 다음과 같은 출력을 볼 수 있습니다:

MariaDB [student]> SOURCE /home/labex/project/answer.sql
+----------------+
| sname          |
+----------------+
| Michael Brown  |
| William Wilson |
| Richard Taylor |
| Charles Thomas |
+----------------+
4 rows in set (0.013 sec)

+-----+---------------+
| sno | sname         |
+-----+---------------+
|   1 | James Johnson |
|   6 | David Moore   |
+-----+---------------+
2 rows in set (0.000 sec)

+----------------+
| sname          |
+----------------+
| James Johnson  |
| Michael Brown  |
| John Davis     |
| Robert Miller  |
| William Wilson |
| David Moore    |
| Richard Taylor |
+----------------+
7 rows in set (0.000 sec)

+-----+
| sno |
+-----+
|   2 |
|   3 |
|   4 |
|   7 |
+-----+
4 rows in set (0.001 sec)

+----------------+
| sname          |
+----------------+
| William Wilson |
| Richard Taylor |
+----------------+
2 rows in set (0.013 sec)

+-----+
| sno |
+-----+
|   5 |
|   8 |
+-----+
2 rows in set (0.000 sec)

+-----------------+------+-------+
| sname           | cno  | grade |
+-----------------+------+-------+
| James Johnson   |   11 |    50 |
| James Johnson   |   12 |    80 |
| James Johnson   |   13 |    50 |
| James Johnson   |   14 |    50 |
| James Johnson   |   15 |    50 |
| Michael Brown   |   11 |    70 |
| Michael Brown   |   12 |    65 |
| Michael Brown   |   15 |    70 |
| John Davis      |   11 |    90 |
| John Davis      |   12 |    70 |
| John Davis      |   14 |    80 |
| John Davis      |   15 |    90 |
| Robert Miller   |   11 |    80 |
| Robert Miller   |   12 |    50 |
| Robert Miller   |   13 |    70 |
| Robert Miller   |   14 |    62 |
| Robert Miller   |   15 |    80 |
| William Wilson  |   11 |    40 |
| William Wilson  |   12 |    90 |
| William Wilson  |   13 |    60 |
| William Wilson  |   15 |    61 |
| David Moore     |   11 |    30 |
| David Moore     |   12 |    50 |
| David Moore     |   13 |    40 |
| David Moore     |   14 |    30 |
| David Moore     |   15 |    35 |
| Richard Taylor  |   11 |    90 |
| Richard Taylor  |   12 |    80 |
| Richard Taylor  |   13 |    80 |
| Richard Taylor  |   15 |    80 |
| Joseph Anderson |   12 |    90 |
| Joseph Anderson |   14 |    70 |
| Joseph Anderson |   15 |    95 |
| Charles Thomas  | NULL |  NULL |
+-----------------+------+-------+
34 rows in set (0.001 sec)

+-----+------+
| sno | SG   |
+-----+------+
|   4 |  342 |
|   7 |  330 |
|   3 |  330 |
|   1 |  280 |
|   5 |  251 |
|   6 |  185 |
+-----+------+
6 rows in set (0.000 sec)
✨ 솔루션 확인 및 연습

요약

축하합니다! 이 프로젝트를 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 기술을 향상시킬 수 있습니다.