inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[백문이불여일타] 데이터 분석을 위한 고급 SQL 문제풀이

Set 1 문제 목록

set1. Contest Leaderboard 질문드려요!

164

[SQL 실전반 7기]gino

작성한 질문수 3

0

안녕하세요. 

Contest Leaderboard 를 풀다가 궁금한 점이 있어서 질문드립니다. 

 

선미님은 FROM 절 서브쿼리로 문제를 푸셨는데, 

저는 SELECT절 서브쿼리로 풀고 있었습니다. 

 

토대가 되는 쿼리는 비슷한 것 같은데  오류가 나네욥 ㅠㅠ 

 

아래 쿼리 한번만 확인해주시면 감사합니다.

더불어 본문제에서는 SELECT절 서브쿼리가 FROM절 서브쿼리보다 별로인가요? 

 

SELECT h.hacker_id
     , h.name
     , (SELECT SUM(max_score) AS mx
        FROM (
                SELECT hacker_id
                     , challenge_id
                     , MAX(score) AS max_score
                FROM submissions
                GROUP BY hacker_id, challenge_id
                 ) sub
        WHERE s.hacker_id = sub.hacker_id
        GROUP BY hacker_id
         HAVING mx != 0
       ) total_score
FROM submissions s
 INNER JOIN hackers h ON h.hacker_id = s.hacker_id
GROUP BY h.hacker_id, h.name
ORDER BY total_score DESC, h.hacker_id

sql

답변 1

0

지식공유자 J

두 가지를 수정하셔야 정답 처리가 됩니다.

1. 아래에서 두 번째 줄 GROUP BY는 빼고, SELECT 절에 DISTINCT를 포함해 중복되는 row를 제외합니다.
SELECT 절의 서브쿼리 안에서 이미 SUM 연산을 해서 값을 가져오기 때문에 다시 GROUP BY를 할 필요가 없습니다. 그리고 h 테이블에서 hacker_id, name만 가져오면 두 값이 모두 동일한 row가 여러 개 나오는데, 이 모든 row와 SUM 연산 값이 붙으면서 중복 데이터가 추출됩니다. 모든 컬럼 값이 동일한 데이터는 한 번씩만 출력될 수 있도록 DISTINCT를 써 주셔야 합니다.

2. SUM(max_score)가 0인 데이터를 제외하기 위해서는 SELECT 절의 서브쿼리 안이 아니라, 바깥에서 조건을 줍니다.
SUM 연산 값은 서브쿼리 안에서 만들어서 가져오지만, 나머지 컬럼인 hacker_id, name와 서브쿼리 밖에서 만나기 때문에 그 row 자체가 추출에서 제외되는 것이 아니라 hacker_id, name은 살아있고 SUM 연산 값 자리만 null로 출력됩니다. (직접 출력값 확인해 보시면 무슨 말인지 이해하기 쉬우실 거에요.) 
바깥에서 WHERE total_score != 0 조건을 통해 필터링을 해야 하는데요. 안타깝게도 WHERE 절에서는 SELECT 절에서 alias로 준 별명(total_score)를 사용하지 못 합니다. 그런데 total_score는 서브쿼리를 통해 만든 컬럼이므로, 그 긴 쿼리를 WHERE 절에 전부 다시 써 주는 것은 권장하지 않고요. FROM 절 서브쿼리로 한 번 더 묶어 주는 편이 낫습니다.

위 1, 2번 내용을 적용해 작성한 쿼리는 아래와 같습니다.

SELECT hacker_id, name, total_score
FROM (
    SELECT DISTINCT h.hacker_id, h.name
        , (SELECT SUM(max_score) AS mx
           FROM (SELECT hacker_id, challenge_id, MAX(score) AS max_score
                         FROM submissions 
                         GROUP BY hacker_id, challenge_id) sub
           WHERE s.hacker_id = sub.hacker_id
           GROUP BY hacker_id) AS total_score
    FROM submissions s
        INNER JOIN hackers h ON h.hacker_id = s.hacker_id
) a
WHERE total_score != 0
ORDER BY total_score DESC, hacker_id

보시다시피 서브쿼리를 세 번이나 사용해야 하므로 효율적인 쿼리는 아니며, 다른 사람이 읽고 이해하기에도 쉽지 않습니다.
강의에서 알려드린 것처럼 FROM 절 서브쿼리 한 번만 사용하는 것이 더 간단하고 효율적인 방법이라고 말씀 드릴 수 있겠네요!

강의기간 연장문의

0

107

2

HackerRank : Weather Observation Station 11 문제풀이

0

124

1

SET4의 3번 자리바꾸기 문제 다른 풀이

0

197

1

set 3의 3번 문제- 데이터의 개수가 짝수일 때 질문

0

277

2

set 1 - 2번 문제풀이

0

270

1

세트2번 Binary Tree Nodes 질문입니다!

0

231

2

고급문제풀이set1 3번 문제

0

255

2

고급문제풀이 3번 INNERJOIN 활용시 오류

0

274

1

회사일하다 보니까 다 못듣고 수강기간이 다끝나가는데 .,. 수강기간 연장은 어떻게 할수 있나요?ㅜㅜ

0

325

1

[Weather 20 ] 2번째 쿼리도 따라 했는데 왜 다 실패일까요?

0

382

1

[Weather 20] 따라 했는데 왜 작동 안해요?

0

283

1

weather-20 왜 작동 안하는건가요?

0

233

1

Ollivander's Inventory 윈도우 함수 min() over

0

320

1

LeetCode 626. Exchange Seats 리트코드 제출 오류

0

510

2

섹션4에 3번 문제풀이 질문

0

386

2

SQL Project Planning 풀이 관련 문의

0

589

2

섹션 1번 4번문제 풀이

1

290

1

섹션1 2번 문제풀이 강의

0

309

1

set2 - 1 같게 작성했는데 답이 이상합니다.

0

289

1

max함수를 써서 풀지는 못하나요?

0

306

1

윈도우 함수를 이용해서 풀고 싶어서 써봤습니다. 더 간단하게 줄일 수 있을까요?

0

265

1

(Hacker Rank)Binary Tree 문제 질문

0

329

1

쿼리 두개로 작성하고 싶지 않아 하나로 어떻게든 만들어 봤습니다.

0

300

1

이런 풀이는 왜 안되는지 궁금해요

0

280

1