├── .DS_Store ├── Leetcode SQL practice ├── .DS_Store └── SQL.md ├── README.md └── Stanford SQL practice ├── .DS_Store ├── SQL exercise.Rmd ├── SQL_exercise.html └── SQL_exercise.pdf /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangruinju/SQL_Resources/4aa5a585c585d4d8110514164c4879363076c010/.DS_Store -------------------------------------------------------------------------------- /Leetcode SQL practice/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangruinju/SQL_Resources/4aa5a585c585d4d8110514164c4879363076c010/Leetcode SQL practice/.DS_Store -------------------------------------------------------------------------------- /Leetcode SQL practice/SQL.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Easy/Medium/Hard" 3 | author: "Rui Wang" 4 | date: "1/16/2017" 5 | output: html_document 6 | --- 7 | 8 | 595. Big Countries 9 | 10 | ```sql 11 | -- Write your MySQL query statement below 12 | select 13 | name, 14 | population, 15 | area 16 | from World 17 | where area >= 3000000 or population >= 25000000 18 | ``` 19 | 613. Shortest Distance in a Line 20 | 21 | ```sql 22 | -- Write your MySQL query statement below 23 | select min(abs(p1.x - p2.x)) as shortest 24 | from point p1, point p2 25 | where p1.x > p2.x 26 | order by shortest 27 | limit 1 28 | ``` 29 | 30 | 627. Swap Salary 31 | 32 | ```sql 33 | UPDATE salary 34 | SET sex = (CASE WHEN sex = 'm' 35 | THEN 'f' 36 | ELSE 'm' 37 | END) 38 | ``` 39 | 584. Find Customer Referee 40 | 41 | ```sql 42 | select name 43 | from customer 44 | where referee_id is null or referee_id <> '2' 45 | ``` 46 | 47 | 620. Not Boring Movies 48 | 49 | ```sql 50 | -- Write your MySQL query statement below 51 | select * from cinema 52 | where mod(id, 2) = 1 53 | and description <> "boring" 54 | order by rating desc 55 | ``` 56 | 610. Triangle Judgement 57 | 58 | ```sql 59 | select *, 60 | case when x+y <= z or y+z <= x or x+z <= y then 'No' 61 | else 'Yes' end as triangle 62 | from triangle 63 | ``` 64 | 586. Customer Placing the Largest Number of Orders 65 | 66 | ```sql 67 | select customer_number 68 | from orders 69 | group by customer_number 70 | order by count(*) desc 71 | limit 1 72 | # tie case 73 | # select a.customer_number 74 | # from 75 | # (select customer_number, count(*) as cnt 76 | # from orders 77 | # group by customer_number) a 78 | # where a.cnt == (select count(*) as cnt from orders group by customer_number order by cnt desc limit 1) 79 | ``` 80 | 603. Consecutive Available Seats 81 | 82 | ```sql 83 | select distinct c1.seat_id 84 | from cinema c1, cinema c2 85 | where c1.free = 1 and c2.free = 1 86 | and (c1.seat_id - 1 = c2.seat_id or c1.seat_id + 1 = c2.seat_id) 87 | order by c1.seat_id 88 | ``` 89 | 577. Employee Bonus 90 | 91 | ```sql 92 | select name, bonus 93 | from Employee e 94 | left join Bonus b 95 | on e.empId = b.empId 96 | where bonus is null or bonus < 1000 97 | ``` 98 | 607. Sales Person 99 | 100 | ```sql 101 | select name 102 | from salesperson 103 | where sales_id not in 104 | ( 105 | select sales_id 106 | from orders o 107 | join company c 108 | on o.com_id = c.com_id 109 | where c.name = 'RED' 110 | ) 111 | ``` 112 | 113 | 597. Friend Requests I: Overall Acceptance Rate 114 | 115 | ```sql 116 | select round( 117 | ifnull( 118 | (select count(*) from (select distinct requester_id, accepter_id from request_accepted) a) 119 | / 120 | (select count(*) from (select distinct sender_id, send_to_id from friend_request) b) 121 | , 0) 122 | , 2) as accept_rate 123 | ``` 124 | 125 | 619. Biggest Single Number 126 | 127 | ```sql 128 | select max(num) as num 129 | from ( 130 | select num 131 | from number 132 | group by num 133 | having count(*) = 1 134 | ) a 135 | ``` 136 | 137 | 182. Duplicate Emails 138 | 139 | ```sql 140 | -- Write your MySQL query statement below 141 | SELECT Email FROM Person 142 | GROUP BY Email 143 | HAVING COUNT(Email)>1 144 | ``` 145 | 146 | 175. Combine Two Tables 147 | 148 | ```sql 149 | -- Write your MySQL query statement below 150 | SELECT Person.FirstName, 151 | Person.LastName, 152 | Address.City, 153 | Address.State 154 | from Person 155 | LEFT JOIN Address 156 | on Person.PersonId = Address.PersonId; 157 | ``` 158 | 159 | 181. Employees Earning More Than Their Managers 160 | 161 | ```sql 162 | -- Write your MySQL query statement below 163 | select e1.name as Employee 164 | from Employee e1, Employee e2 165 | where e1.ManagerId = e2.Id and e1.Salary > e2.Salary; 166 | ``` 167 | 168 | 183. Customers Who Never Order 169 | 170 | ```sql 171 | -- Write your MySQL query statement below 172 | select Name as Customers 173 | from Customers 174 | where Id not in (select CustomerId from Orders); 175 | ``` 176 | 177 | 197. Rising Temperature 178 | 179 | ```sql 180 | -- Write your MySQL query statement below 181 | select w1.Id 182 | from Weather w1, Weather w2 183 | where ( DATEDIFF(w1.Date, w2.Date)=1 ) 184 | and w1.Temperature > w2.Temperature; 185 | ``` 186 | 187 | 596. Classes More Than 5 Students 188 | 189 | ```sql 190 | -- Write your MySQL query statement below 191 | select class 192 | from courses 193 | group by class 194 | having count(distinct student)>=5; 195 | ``` 196 | 197 | 196. Delete Duplicate Emails 198 | 199 | ```sql 200 | -- Write your MySQL query statement below 201 | delete p1 202 | from Person p1, Person p2 203 | where p1.Email = p2.Email 204 | and p1.Id > p2.Id; 205 | ``` 206 | 207 | 176. Second Highest Salary 208 | 209 | ```sql 210 | -- Write your MySQL query statement below 211 | select 212 | max(Salary) as SecondHighestSalary 213 | from Employee 214 | where Salary < (select Max(salary) from Employee); 215 | ``` 216 | 570. Managers with at Least 5 Direct Reports 217 | 218 | ```sql 219 | select Name from Employee 220 | where Id in ( 221 | select distinct ManagerId 222 | from Employee 223 | where ManagerId is not null 224 | group by ManagerId 225 | having count(ManagerId) >= 5 226 | ) 227 | ``` 228 | 229 | 608. Tree Node 230 | 231 | ```sql 232 | select id, 233 | case 234 | when p_id is null then 'Root' 235 | when id in (select distinct p_id from tree) then 'Inner' 236 | else 'Leaf' end as Type 237 | from tree 238 | order by id 239 | ``` 240 | 241 | 612. Shortest Distance in a Plane 242 | 243 | ```sql 244 | select round(sqrt(power(p1.x-p2.x, 2)+power(p1.y-p2.y, 2)), 2) as shortest 245 | from point_2d p1, point_2d p2 246 | where p1.x <> p2.x or p1.y <> p2.y 247 | order by shortest 248 | limit 1 249 | ``` 250 | 251 | 585. Investments in 2016 252 | 253 | ```sql 254 | select round(sum(TIV_2016), 2) as TIV_2016 255 | from insurance 256 | where 257 | TIV_2015 in (select TIV_2015 from insurance group by TIV_2015 having count(*) > 1) 258 | and (LAT, LON) in (select LAT, LON from insurance group by LAT, LON having count(*) = 1) 259 | ``` 260 | 602. Friend Requests II: Who Has the Most Friends 261 | 262 | ```sql 263 | select id, count(*) as num 264 | from 265 | (select requester_id as id 266 | from request_accepted 267 | union all 268 | select accepter_id 269 | from request_accepted) a 270 | group by id 271 | order by num desc 272 | limit 1 273 | ``` 274 | 275 | 580. Count Student Number in Departments 276 | 277 | ```sql 278 | select dept_name, 279 | ifnull(count(distinct student_id), 0) as student_number 280 | from department d 281 | left join student s 282 | on d.dept_id = s.dept_id 283 | group by d.dept_id 284 | order by student_number desc, dept_name 285 | ``` 286 | 574. Winning Candidate 287 | 288 | ```sql 289 | select Name 290 | from Candidate c 291 | join 292 | ( 293 | select CandidateId, count(*) as cnt 294 | from Vote 295 | group by CandidateId 296 | order by cnt desc 297 | limit 1 298 | ) a 299 | on c.id = a.CandidateId 300 | ``` 301 | 302 | 578. Get Highest Answer Rate Question 303 | 304 | ```sql 305 | select question_id as survey_log 306 | from 307 | ( 308 | select question_id, count(answer_id)/count(question_id) as rate 309 | from survey_log 310 | group by question_id 311 | order by rate desc 312 | limit 1 313 | ) a 314 | ``` 315 | 316 | 614. Second Degree Follower 317 | 318 | ```sql 319 | select f1.follower, count(distinct f2.follower) as num 320 | from follow f1 321 | join follow f2 322 | on f1.follower = f2.followee 323 | group by f1.follower 324 | order by f1.follower, num desc 325 | ``` 326 | 618. Students Report By Geography 327 | 328 | ```sql 329 | set @r1 = 0; 330 | set @r2 = 0; 331 | set @r3 = 0; 332 | 333 | select 334 | America.name as America, Asia.name as Asia, Europe.name as Europe 335 | from 336 | (select name, @r1:= @r1+1 as id from student where continent = 'America' order by name) America 337 | left join 338 | (select name, @r2:= @r2+1 as id from student where continent = 'Asia' order by name) Asia 339 | on 340 | America.id = Asia.id 341 | left join 342 | (select name, @r3:= @r3+1 as id from student where continent = 'Europe' order by name) Europe 343 | on 344 | America.id = Europe.id 345 | ``` 346 | 347 | 571. Find Median Given Frequency of Numbers 348 | 349 | ```sql 350 | select avg(n1.Number) as median 351 | from Numbers n1 352 | where n1.Frequency >= abs( 353 | (select sum(n2.Frequency) from Numbers n2 where n1.Number >= n2.Number) 354 | - 355 | (select sum(n2.Frequency) from Numbers n2 where n1.Number <= n2.Number) 356 | ) 357 | ``` 358 | 359 | 178. Rank Scores 360 | 361 | ```sql 362 | -- Write your MySQL query statement below 363 | select s1.Score, 364 | (select count(distinct s2.Score) from Scores s2 where s2.Score >= s1.Score) as Rank 365 | from Scores s1 366 | order by s1.Score desc; 367 | ``` 368 | 369 | 569. Median Employee Salary 370 | 371 | ```sql 372 | select e1.* 373 | from Employee e1, Employee e2 374 | where e1.Company = e2.Company 375 | group by e1.Company, e1.Salary 376 | having sum(case when e1.Salary = e2.Salary then 1 else 0 end) 377 | >= abs(sum(sign(e1.Salary-e2.Salary))) 378 | order by e1.Company, e1.Salary, e1.Id 379 | ``` 380 | 381 | 180. Consecutive Numbers 382 | 383 | ```sql 384 | -- Write your MySQL query statement below 385 | select distinct l1.Num as ConsecutiveNums 386 | from Logs l1, Logs l2, Logs l3 387 | where l1.ID - 1 = l2.ID 388 | and l1.ID - 2 = l3.ID 389 | and l1.Num = l2.Num 390 | and l1.Num = l3.Num; 391 | ``` 392 | 393 | 615. Average Salary: Departments VS Company 394 | 395 | ```sql 396 | select a.pay_month, a.department_id, 397 | case when a.avg_mon_dept_amount = b.avg_dept_amount then 'same' 398 | when a.avg_mon_dept_amount > b.avg_dept_amount then 'higher' 399 | else 'lower' end as comparison 400 | from 401 | (select Date_Format(pay_date, '%Y-%m') as pay_month, department_id, avg(amount) as avg_mon_dept_amount 402 | from salary s 403 | join employee e 404 | on s.employee_id = e.employee_id 405 | group by pay_month, department_id) a 406 | join 407 | (select Date_Format(pay_date, '%Y-%m') as pay_month, avg(amount) as avg_dept_amount 408 | from salary s 409 | join employee e 410 | on s.employee_id = e.employee_id 411 | group by pay_month) b 412 | on a.pay_month = b.pay_month 413 | ``` 414 | 415 | 184. Department Highest Salary 416 | 417 | ```sql 418 | -- Write your MySQL query statement below 419 | select d.Name as Department, e1.Name as Employee, e1.Salary 420 | from Department d, Employee e1 421 | where d.Id = e1.DepartmentId 422 | and (DepartmentId, Salary) in 423 | (select e2.DepartmentId, max(e2.Salary) as max_salary from Employee e2 group by e2.DepartmentId) ; 424 | ``` 425 | 426 | 579. Find Cumulative Salary of an Employee 427 | 428 | ```sql 429 | select e1.Id, e1.Month, sum(e2.Salary) as Salary 430 | from Employee e1, Employee e2 431 | where 432 | e1.Id = e2.Id 433 | and e1.Month - e2.Month >= 0 434 | and e1.Month - e2.Month < 3 435 | and (e1.Id, e1.Month) not in (select Id, max(Month) from Employee group by Id) 436 | group by e1.Id, e1.Month 437 | order by e1.Id, e1.Month desc 438 | ``` 439 | 440 | 177. Nth Highest Salary 441 | 442 | ```sql 443 | CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT 444 | BEGIN 445 | set N = N-1; 446 | RETURN ( 447 | -- Write your MySQL query statement below. 448 | select distinct Salary from Employee order by Salary desc limit N,1 449 | ); 450 | END 451 | ``` 452 | 453 | 601. Human Traffic of Stadium 454 | 455 | ```sql 456 | -- Write your MySQL query statement below 457 | SELECT t.* FROM stadium t 458 | LEFT JOIN stadium p1 ON t.id - 1 = p1.id 459 | LEFT JOIN stadium p2 ON t.id - 2 = p2.id 460 | LEFT JOIN stadium n1 ON t.id + 1 = n1.id 461 | LEFT JOIN stadium n2 ON t.id + 2 = n2.id 462 | WHERE (t.people >= 100 AND p1.people >= 100 AND p2.people >= 100) 463 | OR (t.people >= 100 AND n1.people >= 100 AND n2.people >= 100) 464 | OR (t.people >= 100 AND n1.people >= 100 AND p1.people >= 100) 465 | ORDER BY id; 466 | ``` 467 | 468 | 185. Department Top Three Salaries 469 | 470 | ```sql 471 | -- Write your MySQL query statement below 472 | select d.Name Department, e1.Name Employee, e1.Salary 473 | from Employee e1 474 | join Department d 475 | on e1.DepartmentId = d.Id 476 | where 3 > (select count(distinct(e2.Salary)) 477 | from Employee e2 478 | where e2.Salary > e1.Salary 479 | and e1.DepartmentId = e2.DepartmentId); 480 | ``` 481 | 482 | 262. Trips and Users 483 | 484 | ```sql 485 | -- Write your MySQL query statement below 486 | 487 | select Request_at as Day, 488 | round(sum(case when Status like 'cancelled_%' then 1 else 0 end) / count(*),2) as 'Cancellation Rate' 489 | from Trips 490 | join Users 491 | on Users_Id = Client_Id 492 | where Banned = 'No' 493 | and Request_at between '2013-10-01' and '2013-10-03' 494 | group by Request_at; 495 | ``` 496 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SQL exercise solution 2 | 3 | ## [Intro to Database](https://lagunita.stanford.edu/courses/Engineering/db/2014_1/about) 4 | * [My Practice](https://github.com/wangruinju/SQL_Resources/blob/master/Stanford%20SQL%20practice/SQL%20exercise.Rmd) 5 | 6 | ## [Leetcode DataBase](https://leetcode.com/problemset/database/) 7 | * [My Practice](https://github.com/wangruinju/SQL_Resources/blob/master/Leetcode%20SQL%20practice/SQL.md) 8 | 9 | ## [Vertabelo Academy SQL module](https://academy.vertabelo.com/) 10 | 11 | * SQL Basics (100% completed, 129/129) 12 | 13 | * Operating on Data in SQL (100% completed, 19/19) 14 | 15 | * Creating Tables in SQL (not purchased 8% completed, 15/177) 16 | 17 | * Standard SQL Functions (100% completed, 211/211) 18 | 19 | * Window Functions (100% completed, 218/218) 20 | 21 | ## Good resources for look-up 22 | 23 | https://www.w3schools.com/SQl/default.asp 24 | 25 | http://www.sqlite.org/cli.html 26 | 27 | http://codex.cs.yale.edu/avi/db-book/db6/slide-dir/index.html -------------------------------------------------------------------------------- /Stanford SQL practice/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangruinju/SQL_Resources/4aa5a585c585d4d8110514164c4879363076c010/Stanford SQL practice/.DS_Store -------------------------------------------------------------------------------- /Stanford SQL practice/SQL exercise.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Stanford SQL exercise" 3 | author: "Rui Wang" 4 | date: "3/14/2017" 5 | output: 6 | pdf_document: default 7 | html_document: default 8 | --- 9 | Not the best code, but as a good reference for people are stuck with these problems. 10 | Thanks for Standford online course. 11 | 12 | ### Movie-Rating Query Exercise 13 | 14 | Movie ( mID, title, year, director ) 15 | English: There is a movie with ID number mID, a title, a release year, and a director. 16 | 17 | Reviewer ( rID, name ) 18 | English: The reviewer with ID number rID has a certain name. 19 | 20 | Rating ( rID, mID, stars, ratingDate ) 21 | English: The reviewer rID gave the movie mID a number of stars rating (1-5) on a certain ratingDate. 22 | 23 | Find the titles of all movies directed by Steven Spielberg. 24 | 25 | ```sql 26 | select title from Movie 27 | where director = 'Steven Spielberg'; 28 | ``` 29 | 30 | Find all years that have a movie that received a rating of 4 or 5, and sort them in increasing order. 31 | 32 | ```sql 33 | select distinct year from Movie 34 | join Rating on Movie.mID = Rating.mID 35 | where stars = 4 or stars = 5 36 | order by year; 37 | ``` 38 | Find the titles of all movies that have no ratings. 39 | 40 | ```sql 41 | select title from Movie 42 | left outer join Rating on Movie.mID = Rating.mID 43 | where stars is null; 44 | ``` 45 | 46 | Some reviewers didn't provide a date with their rating. Find the names of all reviewers who have ratings with a NULL value for the date. 47 | 48 | ```sql 49 | select name from Rating 50 | left outer join Reviewer 51 | on Reviewer.rID = Rating.rID 52 | where ratingDate is null; 53 | ``` 54 | 55 | Write a query to return the ratings data in a more readable format: reviewer name, movie title, stars, and ratingDate. Also, sort the data, first by reviewer name, then by movie title, and lastly by number of stars. 56 | 57 | ```sql 58 | select name, title, stars, ratingDate 59 | from Rating join Movie using (mID) 60 | join Reviewer using (rID) 61 | order by name, title, stars; 62 | ``` 63 | 64 | For all cases where the same reviewer rated the same movie twice and gave it a higher rating the second time, return the reviewer's name and the title of the movie. 65 | 66 | ```sql 67 | select name, title from Rating r1 68 | join Rating r2 on(r1.rID=r2.rID and r1.mID=r2.mID) 69 | join Movie on(Movie.mID = r1.mID) 70 | join Reviewer on(Reviewer.rID = r1.rID) 71 | where r1.stars < r2.stars 72 | and r1.ratingDate < r2.ratingDate 73 | and r1.rID in ( select rID from Rating 74 | group by rID, mID 75 | having count(*) = 2); 76 | ``` 77 | 78 | For each movie that has at least one rating, find the highest number of stars that movie received. Return the movie title and number of stars. Sort by movie title. 79 | 80 | ```sql 81 | select title, max(stars) 82 | from Rating 83 | join Movie on(Rating.mID = Movie.mID) 84 | join Reviewer on(Rating.rID = Reviewer.rID) 85 | where Rating.mID in 86 | (select mID from Rating group by mID 87 | having count(stars) >= 1) 88 | group by title 89 | order by title 90 | ``` 91 | 92 | For each movie, return the title and the 'rating spread', that is, the difference between highest and lowest ratings given to that movie. Sort by rating spread from highest to lowest, then by movie title. 93 | 94 | ```sql 95 | select title, max(stars) - min(stars) as rating_spread 96 | from Rating 97 | join Movie using(mID) 98 | join Reviewer using(rID) 99 | group by title 100 | order by rating_spread desc; 101 | ``` 102 | 103 | Find the difference between the average rating of movies released before 1980 and the average rating of movies released after 1980. (Make sure to calculate the average rating for each movie, then the average of those averages for movies before 1980 and movies after. Don't just calculate the overall average rating before and after 1980.) 104 | 105 | ```sql 106 | select 107 | (select avg(avg_rating) 108 | from (select year, avg(stars) as avg_rating 109 | from Rating 110 | join Movie using(mID) 111 | join Reviewer using(rID) 112 | group by year) 113 | where year < 1980) 114 | - 115 | (select avg(avg_rating) 116 | from (select year, avg(stars) as avg_rating 117 | from Rating 118 | join Movie using(mID) 119 | join Reviewer using(rID) 120 | group by year) 121 | where year > 1980); 122 | ``` 123 | 124 | Find the names of all reviewers who rated Gone with the Wind. 125 | 126 | ```sql 127 | select distinct name 128 | from Rating 129 | join Movie using(mID) 130 | join Reviewer using(rID) 131 | where title = 'Gone with the Wind'; 132 | ``` 133 | 134 | For any rating where the reviewer is the same as the director of the movie, return the reviewer name, movie title, and number of stars. 135 | 136 | ```sql 137 | select distinct name, title, stars 138 | from Rating 139 | join Movie using(mID) 140 | join Reviewer using(rID) 141 | where name = director; 142 | ``` 143 | 144 | Return all reviewer names and movie names together in a single list, alphabetized. (Sorting by the first name of the reviewer and first word in the title is fine; no need for special processing on last names or removing "The".) 145 | 146 | ```sql 147 | select name from 148 | (select distinct name 149 | from Reviewer 150 | union 151 | select distinct title 152 | from Movie) 153 | order by name; 154 | ``` 155 | Find the titles of all movies not reviewed by Chris Jackson. 156 | 157 | ```sql 158 | select title from Movie 159 | where mID not in 160 | (select mID from Rating where rID in 161 | (select rID from Reviewer 162 | where name = 'Chris Jackson')) 163 | ``` 164 | 165 | For all pairs of reviewers such that both reviewers gave a rating to the same movie, return the names of both reviewers. Eliminate duplicates, don't pair reviewers with themselves, and include each pair only once. For each pair, return the names in the pair in alphabetical order. 166 | 167 | ```sql 168 | select distinct Re1.name, Re2.name 169 | from Rating R1, Rating R2, Reviewer Re1, Reviewer Re2 170 | where R1.mID = R2.mID 171 | and R1.rID = Re1.rID 172 | and R2.rID = Re2.rID 173 | and Re1.name < Re2.name 174 | order by Re1.name, Re2.name; 175 | ``` 176 | 177 | For each rating that is the lowest (fewest stars) currently in the database, return the reviewer name, movie title, and number of stars. 178 | 179 | ```sql 180 | select name, title, stars 181 | from Rating 182 | join Movie using(mID) 183 | join Reviewer using(rID) 184 | where stars <= (select min(stars) from Rating); 185 | ``` 186 | 187 | List movie titles and average ratings, from highest-rated to lowest-rated. If two or more movies have the same average rating, list them in alphabetical order. 188 | 189 | ```sql 190 | select title, avg(stars) as avg 191 | from Rating 192 | join Movie using(mID) 193 | join Reviewer using(rID) 194 | group by title 195 | order by avg desc, title; 196 | ``` 197 | 198 | Find the names of all reviewers who have contributed three or more ratings. (As an extra challenge, try writing the query without HAVING or without COUNT.) 199 | 200 | ```sql 201 | select name 202 | from Rating 203 | join Movie using(mID) 204 | join Reviewer using(rID) 205 | group by name 206 | having count(mID) >= 3; 207 | ``` 208 | 209 | Some directors directed more than one movie. For all such directors, return the titles of all movies directed by them, along with the director name. Sort by director name, then movie title. (As an extra challenge, try writing the query both with and without COUNT.) 210 | 211 | ```sql 212 | select title, director from Movie 213 | where director in 214 | ( select director 215 | from movie 216 | group by director 217 | having count(*) > 1) 218 | order by director, title; 219 | ``` 220 | 221 | Find the movie(s) with the highest average rating. Return the movie title(s) and average rating. (Hint: This query is more difficult to write in SQLite than other systems; you might think of it as finding the highest average rating and then choosing the movie(s) with that average rating.) 222 | 223 | ```sql 224 | select title, avg from 225 | (select title, 226 | avg(stars) as avg 227 | from Rating 228 | join Movie using(mID) 229 | join Reviewer using(rID) 230 | group by title) 231 | where avg >= 232 | (select max(avg) from 233 | (select title, 234 | avg(stars) as avg 235 | from Rating 236 | join Movie using(mID) 237 | join Reviewer using(rID) 238 | group by title)); 239 | ``` 240 | 241 | Find the movie(s) with the lowest average rating. Return the movie title(s) and average rating. (Hint: This query may be more difficult to write in SQLite than other systems; you might think of it as finding the lowest average rating and then choosing the movie(s) with that average rating.) 242 | 243 | ```sql 244 | select title, avg 245 | from 246 | (select title, avg(stars) as avg 247 | from Rating 248 | join Movie using(mID) 249 | join Reviewer using(rID) 250 | group by title) 251 | where avg <= 252 | (select min(avg) from 253 | (select title, 254 | avg(stars) as avg 255 | from Rating 256 | join Movie using(mID) 257 | join Reviewer using(rID) 258 | group by title)); 259 | ``` 260 | 261 | For each director, return the director's name together with the title(s) of the movie(s) they directed that received the highest rating among all of their movies, and the value of that rating. Ignore movies whose director is NULL. 262 | 263 | ```sql 264 | select director, title, max(stars) from Rating 265 | join Movie using(mID) 266 | join Reviewer using(rID) 267 | where director is not null 268 | group by director; 269 | ``` 270 | 271 | Add the reviewer Roger Ebert to your database, with an rID of 209. 272 | 273 | ```sql 274 | insert into Reviewer (rID, name) 275 | values ('209', 'Roger Ebert'); 276 | ``` 277 | 278 | Insert 5-star ratings by James Cameron for all movies in the database. Leave the review date as NULL. 279 | 280 | ```sql 281 | insert into Rating (rID, mID, stars, ratingDate ) 282 | select Reviewer.rID , Movie.mID, 5, null from Movie 283 | left outer join Reviewer 284 | where Reviewer.name='James Cameron'; 285 | ``` 286 | 287 | For all movies that have an average rating of 4 stars or higher, add 25 to the release year. (Update the existing tuples; don't insert new tuples.) 288 | 289 | ```sql 290 | update Movie 291 | set year = year + 25 292 | where mID in 293 | (select mID from 294 | (select mID, avg(stars) as avg 295 | from Movie join Rating using(mID) 296 | group by mID) 297 | where avg >= 4); 298 | ``` 299 | 300 | Remove all ratings where the movie's year is before 1970 or after 2000, and the rating is fewer than 4 stars. 301 | 302 | ```sql 303 | delete from rating 304 | where mID in (select mID from movie where year < 1970 or year > 2000) 305 | and stars < 4; 306 | ``` 307 | 308 | ### Social-Network Query Exercise 309 | 310 | Highschooler ( ID, name, grade ) 311 | English: There is a high school student with unique ID and a given first name in a certain grade. 312 | 313 | Friend ( ID1, ID2 ) 314 | English: The student with ID1 is friends with the student with ID2. Friendship is mutual, so if (123, 456) is in the Friend table, so is (456, 123). 315 | 316 | Likes ( ID1, ID2 ) 317 | English: The student with ID1 likes the student with ID2. Liking someone is not necessarily mutual, so if (123, 456) is in the Likes table, there is no guarantee that (456, 123) is also present. 318 | 319 | Find the names of all students who are friends with someone named Gabriel. 320 | 321 | ```sql 322 | select name 323 | from Highschooler 324 | where ID in (select ID1 from Friend where ID2 in 325 | (select ID from Highschooler where name = 'Gabriel')); 326 | ``` 327 | 328 | For every student who likes someone 2 or more grades younger than themselves, return that student's name and grade, and the name and grade of the student they like. 329 | 330 | ```sql 331 | select h1.name, h1.grade, h2.name, h2.grade 332 | from Highschooler h1, Highschooler h2, Likes l 333 | where h1.ID = l.ID1 334 | and h2.ID = l.ID2 335 | and h1.grade >= h2.grade + 2 336 | ``` 337 | 338 | For every pair of students who both like each other, return the name and grade of both students. Include each pair only once, with the two names in alphabetical order. 339 | 340 | ```sql 341 | select h1.name, h1.grade, h2.name, h2.grade 342 | from Highschooler h1, Highschooler h2, Likes l1, Likes l2 343 | where h1.ID = l1.ID1 344 | and h2.ID = l1.ID2 345 | and l1.ID1 = l2.ID2 346 | and l1.ID2 = l2.ID1 347 | and h1.name < h2.name; 348 | ``` 349 | 350 | Find all students who do not appear in the Likes table (as a student who likes or is liked) and return their names and grades. Sort by grade, then by name within each grade. 351 | 352 | ```sql 353 | select name, grade 354 | from Highschooler 355 | where ID not in (select distinct ID1 from Likes) 356 | and ID not in (select distinct ID2 from Likes) 357 | order by grade, name; 358 | ``` 359 | 360 | For every situation where student A likes student B, but we have no information about whom B likes (that is, B does not appear as an ID1 in the Likes table), return A and B's names and grades. 361 | 362 | ```sql 363 | select distinct h1.name, h1.grade, h2.name, h2.grade 364 | from Highschooler h1, Highschooler h2, Likes l1, Likes l2 365 | where h1.ID = l1.ID1 366 | and h2.ID = l1.ID2 367 | and h2.ID not in (select distinct ID1 from Likes); 368 | ``` 369 | 370 | Find names and grades of students who only have friends in the same grade. Return the result sorted by grade, then by name within each grade. 371 | 372 | ```sql 373 | select h1.name, h1.grade 374 | from Highschooler h1, Highschooler h2, Friend f 375 | where h1.ID = f.ID1 and h2.ID = f.ID2 376 | group by h1.name, h1.grade 377 | having count(distinct h2.grade) = 1 378 | order by h1.grade, h1.name; 379 | ``` 380 | 381 | For each student A who likes a student B where the two are not friends, find if they have a friend C in common (who can introduce them!). For all such trios, return the name and grade of A, B, and C. 382 | 383 | ```sql 384 | select distinct h1.name, h1.grade, h2.name, h2.grade, h3.name, h3.grade 385 | from Highschooler h1, Highschooler h2, Highschooler h3, Friend f, Likes l 386 | where h1.ID = l.ID1 and h2.ID = l.ID2 387 | and h2.ID not in (select distinct ID2 from Friend where ID1 = h1.ID) 388 | and h3.ID in (select distinct ID2 from Friend where ID1 = h1.ID 389 | INTERSECT 390 | select distinct ID2 from Friend where ID1 = h2.ID); 391 | ``` 392 | 393 | Find the difference between the number of students in the school and the number of different first names. 394 | 395 | ```sql 396 | select (select count(distinct ID) from Highschooler) 397 | - (select count(distinct name) from Highschooler); 398 | ``` 399 | 400 | Find the name and grade of all students who are liked by more than one other student. 401 | 402 | ```sql 403 | select h1.name, h1.grade 404 | from Highschooler h1 405 | where h1.ID in (select distinct ID2 from Likes group by ID2 having count(ID1) > 1); 406 | ``` 407 | 408 | For every situation where student A likes student B, but student B likes a different student C, return the names and grades of A, B, and C. 409 | 410 | ```sql 411 | select distinct h1.name, h1.grade, h2.name, h2.grade, h3.name, h3.grade 412 | from Highschooler h1, Highschooler h2, Highschooler h3, Likes l 413 | where h1.ID = l.ID1 414 | and h2.ID = l.ID2 415 | and h1.ID not in (select ID2 from Likes where ID1 = h2.ID) 416 | and h3.ID in (select ID2 from Likes where ID1 = h2.ID); 417 | ``` 418 | 419 | Find those students for whom all of their friends are in different grades from themselves. Return the students' names and grades. 420 | 421 | ```sql 422 | select h1.name, h1.grade 423 | from Highschooler h1 424 | where h1.grade not in (select h2.grade from Highschooler h2, 425 | Friend f where f.ID1 = h1.ID and f.ID2 = h2.ID); 426 | ``` 427 | 428 | What is the average number of friends per student? (Your result should be just one number.) 429 | 430 | ```sql 431 | select avg(fr) from 432 | (select count(distinct ID2) as fr from Highschooler, Friend where ID = ID1 group by ID); 433 | ``` 434 | 435 | Find the number of students who are either friends with Cassandra or are friends of friends of Cassandra. Do not count Cassandra, even though technically she is a friend of a friend. 436 | 437 | ```sql 438 | select count(*) -1 from ( 439 | select distinct f2.ID2 from Friend f2 440 | where f2.ID1 in 441 | (select distinct f1.ID2 as s1 from Friend f1 442 | where f1.ID1 = (select ID from Highschooler where name = 'Cassandra')) 443 | union 444 | select distinct f1.ID2 as s1 from Friend f1 445 | where f1.ID1 = (select ID from Highschooler where name = 'Cassandra') ); 446 | ``` 447 | 448 | Find the name and grade of the student(s) with the greatest number of friends. 449 | 450 | ```sql 451 | select h.name, h.grade 452 | from Highschooler h 453 | where ID in 454 | (select ID from 455 | (select ID, count(distinct ID2) as fr from Highschooler, Friend 456 | where ID = ID1 group by ID) 457 | where fr >= (select max(fr) 458 | from 459 | (select ID, count(distinct ID2) as fr from Highschooler, Friend 460 | where ID = ID1 group by ID))); 461 | ``` 462 | 463 | It's time for the seniors to graduate. Remove all 12th graders from Highschooler. 464 | 465 | ```sql 466 | delete from Highschooler 467 | where grade = 12; 468 | ``` 469 | 470 | If two students A and B are friends, and A likes B but not vice-versa, remove the Likes tuple. 471 | ```sql 472 | delete from Likes 473 | where ID1 in (select f.ID1 from Friend f where f.ID2 = Likes.ID2) 474 | and ID1 not in (select l.ID2 from Likes l where l.ID1 = Likes.ID2); 475 | ``` 476 | 477 | For all cases where A is friends with B, and B is friends with C, add a new friendship for the pair A and C. Do not add duplicate friendships, friendships that already exist, or friendships with oneself. (This one is a bit challenging; congratulations if you get it right.) 478 | 479 | ```sql 480 | insert into Friend 481 | select f1.ID1, f2.ID1 from Friend f1, Friend f2 482 | where f1.ID2 = f2.ID2 and f1.ID1 <> f2.ID1 483 | except select * from Friend; 484 | ``` 485 | -------------------------------------------------------------------------------- /Stanford SQL practice/SQL_exercise.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangruinju/SQL_Resources/4aa5a585c585d4d8110514164c4879363076c010/Stanford SQL practice/SQL_exercise.pdf --------------------------------------------------------------------------------