by 머루원해 [SQL Query] [2018.11.06 07:51:29]
Oralce Apex를 배우고 있는 학생입니다. 과제 중에 문제가 있는데 모르겠네요. Eastwood와 작업한 총 횟수를 어떤식으로 풀어야할 지 모르겠네요.. 아래는 문제입니다.
Eastwood는 그의 경력 동안 많은 배우, 감독, 제작자 등과 협력해왔다. 전체 이름(성과 이름으로 결합된 하나의 필드), 역할 및 이들이 Eastwood와 작업한 총 횟수를 나열하는 join query를 작성합니다.
결과를 전체 공동 작업 수로 내림차순으로 정렬하고 가장 빈번한 공동 작업자 10명(FETCH 사용)으로 제한합니다. 결과에 나타나는 계산된 필드의 이름을 변경해야 합니다.
여기서 저는
SELECT PERSON.PersonFirst ||''|| PERSON.PersonMiddle ||''|| PERSON.PersonLast AS CollaboratorName, PRINCIPAL.Role, COUNT(PRINCIPAL.PersonID) AS TotalTime
FROM PERSON JOIN PRINCIPAL ON PERSON.PersonID = PRINCIPAL.PersonID
WHERE PERSON.PersonFirst = 'Clint'
AND PERSON.PersonLast = 'Eastwood'
GROUP BY PERSON.PersonFirst ||''|| PERSON.PersonMiddle ||''|| PERSON.PersonLast AS CollaboratorName, PRINCIPAL.Role
ORDER BY TotalTime DESC
FETCH FIRST 10 ROWS ONLY;
이렇게 했는데 에러가 계속 뜨네요. 제 생각에는 where 부분이 틀린 것 같은데..
어떻게 바꿔야할까요?
에러는 Group By 절에 알리아스 구문 써서 그래요.(AS CollaboratorName)
문제의 설명을 보면 Eastwood 와 작업한 사람의 리스트를 뽑는것 같아요.
작성하신 쿼리는 Eastwood 를 뽑고 있네요.
문제의 설명이 상당히 모호한 표현을 쓰고 있네요.
한국어로 번역하면서 본래의 의미 전달이 잘 안되는 표현을 쓴 것 같네요.
SELECT d.PersonFirst ||' '|| d.PersonMiddle ||' '|| d.PersonLast AS CollaboratorName , c.Role , COUNT(*) AS TotalTime FROM person a -- 1. Eastwood 가 INNER JOIN principal b ON a.PersonID = b.PersonID -- 2. 출연한 영화 INNER JOIN principal c ON b.MovieID = c.MovieID -- 3. 함께 작업한 INNER JOIN person d ON c.PersonID = d.PersonID -- 4. 영화 관계자 WHERE a.PersonFirst = 'Clint' AND a.PersonLast = 'Eastwood' GROUP BY d.PersonFirst ||' '|| d.PersonMiddle ||' '|| d.PersonLast, c.Role ORDER BY TotalTime DESC FETCH FIRST 10 ROWS ONLY ;
한작품에서 1인 2역을 한다거나, 감독겸 배우를 겸한다거나 한다면?
영화관계자 입장에서는 역할 별로 카운트 되니 문제가 없지만
Eastwood 에 해당 사항이 있다면? 카운트가 2배로 나올 듯 하네요.
따라서 쿼리를 바꿔야 하겠네요.
SELECT d.PersonFirst ||' '|| d.PersonMiddle ||' '|| d.PersonLast AS CollaboratorName , c.Role , COUNT(*) AS TotalTime FROM principal c -- 3. 함께 작업한 INNER JOIN person d -- 4. 영화 관계자 ON c.PersonID = d.PersonID WHERE c.MovieID IN (SELECT b.MovieID FROM person a -- 1. Eastwood 가 INNER JOIN principal b -- 2. 출연한 영화 ON a.PersonID = b.PersonID WHERE a.PersonFirst = 'Clint' AND a.PersonLast = 'Eastwood' ) GROUP BY d.PersonFirst ||' '|| d.PersonMiddle ||' '|| d.PersonLast, c.Role ORDER BY TotalTime DESC FETCH FIRST 10 ROWS ONLY ;
-- 해당 조건을 AND 절로 추가하면 되는데요. -- 부정 조건이라 조금 까다로울수는 있습니다. -- 우선 긍정 조건을 작성 하신 뒤 AND (d.PersonFirst = 'Clint' AND d.PersonLast = 'Eastwood') -- 조건 앞에 NOT 을 붙여주면 됩니다. AND NOT (d.PersonFirst = 'Clint' AND d.PersonLast = 'Eastwood') -- 이렇게 해도 되고, NOT 을 괄호 안으로 넣을 수 있는데. AND (d.PersonFirst != 'Clint' OR d.PersonLast <> 'Eastwood') -- 이런식으로 비교구문과 AND 구문이 모두 바뀝니다.