Table: Movies
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| movie_id | int |
| title | varchar |
+---------------+---------+
movie_id is the primary key (column with unique values) for this table.
title is the name of the movie.
Table: Users
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| user_id | int |
| name | varchar |
+---------------+---------+
user_id is the primary key (column with unique values) for this table.
The column 'name' has unique values.
Table: MovieRating
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| movie_id | int |
| user_id | int |
| rating | int |
| created_at | date |
+---------------+---------+
(movie_id, user_id) is the primary key (column with unique values) for this table.
This table contains the rating of a movie by a user in their review.
created_at is the user's review date.
Write a solution to:
Find the name of the user who has rated the greatest number of movies. In case of a tie, return the lexicographically smaller user name.
Find the movie name with the highest average rating in February 2020. In case of a tie, return the lexicographically smaller movie name.
The result format is in the following example.
Example 1:
Input:
Movies table:
+-------------+--------------+
| movie_id | title |
+-------------+--------------+
| 1 | Avengers |
| 2 | Frozen 2 |
| 3 | Joker |
+-------------+--------------+
Users table:
+-------------+--------------+
| user_id | name |
+-------------+--------------+
| 1 | Daniel |
| 2 | Monica |
| 3 | Maria |
| 4 | James |
+-------------+--------------+
MovieRating table:
+-------------+--------------+--------------+-------------+
| movie_id | user_id | rating | created_at |
+-------------+--------------+--------------+-------------+
| 1 | 1 | 3 | 2020-01-12 |
| 1 | 2 | 4 | 2020-02-11 |
| 1 | 3 | 2 | 2020-02-12 |
| 1 | 4 | 1 | 2020-01-01 |
| 2 | 1 | 5 | 2020-02-17 |
| 2 | 2 | 2 | 2020-02-01 |
| 2 | 3 | 2 | 2020-03-01 |
| 3 | 1 | 3 | 2020-02-22 |
| 3 | 2 | 4 | 2020-02-25 |
+-------------+--------------+--------------+-------------+
Output:
+--------------+
| results |
+--------------+
| Daniel |
| Frozen 2 |
+--------------+
Explanation:
Daniel and Monica have rated 3 movies ("Avengers", "Frozen 2" and "Joker") but Daniel is smaller lexicographically.
Frozen 2 and Joker have a rating average of 3.5 in February but Frozen 2 is smaller lexicographically.
Moives
는 영화의이름 /Users
는 유저이름 /MovieRating
영화 정보
영화를 가장 많이 평가한 사용자의 이름을 찾고 동점이면 사용자의 이름을 사전적 의미로 오름차순으로 반환
2020년 2월에서 평균평점이 가장 높은 영화이름을 찾고 동점일 경우 영화이름을 사전적 의미로 오름차순으로 반환
마지막으로 이름과 영화를 차례대로 반환하는 쿼리를 만들어라.
- MovieRating 테이블과 Users가 join되며 user_id가 max(count)순으로 user_id= 2 , 1이며 유저이름을 오름차순으로 출력
- MovieRating 테이블과 Movies가 join되며 movie_ie기준으로 max(avg(rating))순으로 평균치가 가장 높은 영화이름을 오름차순으로 출력
- 나의 첫번째 방법
WITH UserRatingCounts AS ( SELECT user_id, COUNT(*) as rating_count FROM MovieRating GROUP BY user_id ), MaxRatingCount AS ( SELECT MAX(rating_count) as max_count FROM UserRatingCounts ), FirstQuery AS ( SELECT u.name AS results FROM UserRatingCounts urc JOIN MaxRatingCount mrc ON urc.rating_count = mrc.max_count JOIN Users u ON urc.user_id = u.user_id ORDER BY u.name LIMIT 1 ), AverageRatings AS ( SELECT mr.movie_id, m.title, AVG(mr.rating) AS avg_rating FROM MovieRating mr JOIN Movies m ON mr.movie_id = m.movie_id WHERE mr.created_at BETWEEN '2020-02-01' AND '2020-02-29' GROUP BY mr.movie_id, m.title ), MaxAverageRating AS ( SELECT MAX(avg_rating) AS max_avg_rating FROM AverageRatings ), SecondQuery AS ( SELECT ar.title AS results FROM AverageRatings ar JOIN MaxAverageRating mar ON ar.avg_rating = mar.max_avg_rating ORDER BY ar.title LIMIT 1 ) SELECT results FROM FirstQuery UNION ALL SELECT results FROM SecondQuery;
다른 방법
Write your MySQL query statement below (SELECT name AS results FROM MovieRating JOIN Users USING(user_id) GROUP BY name ORDER BY COUNT(*) DESC, name LIMIT 1) /* using함수를 이용하여 user_id열이라느 컬럼명이 동일한 두 테이블을 결합하며 중복제거됩니다 그후 name으로 그룹화하며 영화 평가를 많이한 순이 동일할 경우 이름을 알파벳 순으로 정렬하며 최상단의 하나를 가져옵니다.*/ UNION ALL (SELECT title AS results FROM MovieRating JOIN Movies USING(movie_id) WHERE EXTRACT(YEAR_MONTH FROM created_at) = 202002 GROUP BY title ORDER BY AVG(rating) DESC, title LIMIT 1); /*위와 같은 방법으로 쿼리를 작성하며 EXTRACT함수를 이용해 년,월의 정보가 2020년2월의 조건을 명시해준 후 union으로 수직 결합 해줍니다.*/
이 접근 방식에는 UNION ALL을 사용하여 결합된 두 개의 개별 쿼리가 포함됩니다.
첫 번째 쿼리는 MovieRating 및 Users 테이블을 활용하여 사용자에 초점을 맞춥니다. 각 사용자에 대한 평점 수를 계산하고, 내림차순으로 결과를 정렬하고, 최상위 결과를 선택합니다.
두 번째 쿼리는 MovieRating 및 Movies 테이블을 사용하여 영화를 중심으로 합니다. 2020년 2월에 생성된 평점을 필터링하고, 각 영화에 대한 평균 평점을 계산하고, 내림차순으로 결과를 평균 평점으로 정렬하고, 최상위 결과를 선택합니다.
첫 번째 쿼리(사용자용):
SELECT name AS results: 사용자 이름을 선택하여 "결과"라는 별칭을 지정합니다
FROM MovieRating JOIN Users USING(user_id). : user_id를 사용하여 MovieRating 및 Users 테이블을 조인합니다.
GROUP BY name: 결과를 사용자 이름으로 그룹화합니다.
ORDER BY COUNT(*) DESC, name: 결과를 평점 수를 내림차순으로 정렬하고, 동점인 경우 사용자 이름을 기준으로 정렬합니다.
LIMIT 1: 정렬된 목록에서 가장 위 행(가장 자주 사용된 사용자)으로 출력을 제한합니다.
두 번째 질의(2020년 2월 영화):
SELECT title AS results: 영화 제목을 선택하여 "결과"라는 별칭을 지정합니다
FROM MovieRating JOIN Movies USING(movie_id). : movie_id를 사용하여 MovieRating 및 Movies 테이블을 조인합니다.
WHERE EXTRACT(YEAR_MONTH FROM created_at) = 202002: 2020년 2월에 생성된 평가를 필터링합니다
GROUP BY title. : 결과를 영화 제목으로 그룹화합니다.
ORDER BY AVG(rating) DESC, title: 결과를 평균 평점을 내림차순으로 정렬하고, 동점이 있는 경우 영화 제목을 기준으로 정렬합니다.
LIMIT 1: 정렬된 목록에서 맨 위 행(2020년 2월에 가장 높은 평가를 받은 영화)으로 출력을 제한합니다.
Union:
두 쿼리의 결과를 결합합니다. " UNION ALL"는 중복된 행이라도 모든 행을 보존하는 데 사용됩니다.
복잡성
시간 복잡도:
첫 번째 쿼리의 시간 복잡도는 JOIN, GROUP BY, ORDER BY 연산의 영향을 받으며, 일반적으로 O(m + n log n)입니다. 여기서 m은 MovieRating 테이블의 행 수이고, n은 고유한 사용자 수입니다. 두 번째 쿼리의 시간 복잡도는 마찬가지로 JOIN, GROUP BY, ORDER BY 연산의 영향을 받으며, 일반적으로 O(p + q log q)입니다. 여기서 p는 2020년 2월 MovieRating 테이블의 행 수이고, q는 고유한 영화 수입니다.
공간 복잡도:
공간 복잡도는 주로 두 쿼리의 결과 집합에 의해 영향을 받습니다. 첫 번째 쿼리의 경우, O(n)이며, 여기서 n은 고유한 사용자 수입니다. 두 번째 쿼리의 경우, O(q)이며, 여기서 q는 고유한 영화 수입니다.