학생 별 시험에 참석한 횟수를 구하시오. (The result table should contain all students and all subjects.)
- subjects 테이블을 사용하지 않고 문제를 풀려다가 학생이 응시하지 않은 과목에대한 0을 출력시키는데 애를 먹었다. 아직까지 내가 알고있는 join의 형태는 한번의 join으로 2개의 테이블을 결합하는 것 뿐이니깐.
- 학생 별 시험과목에만 초점을 두고 subject_name이 examinations 테이블에도 있으니 상관없다고 생각했다.
- 학생별(students 테이블) 수강하고있는 과목(subjects)의 모든 조합을 보여 줄려면 join()을 써야 했다.
JOIN데이터의 일치 조건을 기반으로 두 테이블을 결합하며, 조건이 일치하는 행만 결과에 포함된다. 조건에 따라 더 적은 수의 행을 처리.
CROSS JOIN조건 없이 두 테이블의 모든 행의 조합을 생성합니다. 결과 집합의 행 수는 두 테이블의 행 수를 곱한 값입니다. 두 테이블의 모든 행의 조합을 생성하므로, 결과 집합의 크기가 매우 커질 수 있습니다.SELECT * FROM table1 CROSS JOIN table2;
select s.student_id, s.student_name, su.subject_name, COUNT(e.subject_name) AS attended_exams from students s cross join subjects su #해당 문제는 JOIN을 사용해도 상관없다. left join examinations e on s.student_id = e.student_id and su.subject_name = e.subject_name group by 1,2,3 order by 1,2
CROSS JOIN인데 AND 조건문을 줘야하나?
데이터의 특성과 문제가 요구하는 바에 따라 다를 것. CROSS JOIN은 모든 학생과 모든 과목의 모든 가능한 조합을 생성하지만, 참석 기록을 확인하려면 LEFT JOIN을 사용하여 참석 데이터를 결합해야 합니다.
- LEFT JOIN: 왼쪽 테이블의 모든 데이터를 포함하고, 오른쪽 테이블의 일치하는 데이터를 결합. 일치하지 않는 경우 NULL 포함.
참석하지 않은 과목에 0이 나오는 원리
1. CROSS JOIN 결과와 examinations 테이블을 LEFT JOIN하게 되면
2. ON s.student_id = e.student_id AND su.subject_name = e.subject_name 조건에 따라 일치하는 행이 없는 경우 NULL값이 반환된다.
3. COUNT 함수는 NULL 값을 무시하므로, 참석하지 않은 경우 0으로 계산.
문제의 난이도는 높지 않지만, 아직도 문제에 대한 원리 보단 감에따라 형식적으로 풀다보니 이제까지 풀어온 문제와 형식이 다르면 막힌다. 문제를 더 많이 많이 풀어보면서 케이스를 늘리고 계속해서 개념을 복기해 보는 수 밖에!!
그래서 JOIN과 CROSS JOIN과 INNER JOIN은 어떻게 사용해야 하나?
MySQL에서 JOIN, CROSS JOIN, INNER JOIN은 구문적으로 다소 차이가 있지만, 기본적으로 동일한 결과를 반환하며, 많은 경우 서로 대체 가능하다. 그러나, 약간의 차이점이 있으며 상황에 따라 구문을 선택하는 것이 좋다.
JOIN과 INNER JOIN은 조건에 따라 일치하는 행만 반환한다
CROSS JOIN은 조건 없이 모든 가능한 행의 조합을 반환한다
INNER JOIN은 두 테이블 간의 관계를 기준으로 데이터를 조인할 때 사용된다
CROSS JOIN은 두 테이블의 모든 행을 조합할 때 사용되며, 일반적으로 덜 사용된다
INNER JOIN은 테이블 간의 관계를 나타낼 때 더 명확하다.
CROSS JOIN은 모든 가능한 조합을 생성할 때 사용되며, WHERE 절을 사용하여 조건을 적용할 수 있다.