# 595. Big Countries https://leetcode.com/problems/big-countries/description/ ## Description ```html +-----------------+------------+------------+--------------+---------------+ | name            | continent  | area       | population   | gdp           | +-----------------+------------+------------+--------------+---------------+ | Afghanistan     | Asia       | 652230     | 25500100     | 20343000      | | Albania         | Europe     | 28748      | 2831741      | 12960000      | | Algeria         | Africa     | 2381741    | 37100000     | 188681000     | | Andorra         | Europe     | 468        | 78115        | 3712000       | | Angola          | Africa     | 1246700    | 20609294     | 100990000     | +-----------------+------------+------------+--------------+---------------+ ``` 查找面积超过 3,000,000 或者人口数超过 25,000,000 的国家。 ```html +--------------+-------------+--------------+ | name         | population  | area         | +--------------+-------------+--------------+ | Afghanistan  | 25500100    | 652230       | | Algeria      | 37100000    | 2381741      | +--------------+-------------+--------------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS World; CREATE TABLE World ( NAME VARCHAR ( 255 ), continent VARCHAR ( 255 ), area INT, population INT, gdp INT ); INSERT INTO World ( NAME, continent, area, population, gdp ) VALUES     ( 'Afghanistan', 'Asia', '652230', '25500100', '203430000' ),     ( 'Albania', 'Europe', '28748', '2831741', '129600000' ),     ( 'Algeria', 'Africa', '2381741', '37100000', '1886810000' ),     ( 'Andorra', 'Europe', '468', '78115', '37120000' ),     ( 'Angola', 'Africa', '1246700', '20609294', '1009900000' ); ``` ## Solution ```sql SELECT name,     population,     area FROM     World WHERE     area > 3000000     OR population > 25000000; ``` # 627. Swap Salary https://leetcode.com/problems/swap-salary/description/ ## Description ```html | id | name | sex | salary | |----|------|-----|--------| | 1  | A    | m   | 2500   | | 2  | B    | f   | 1500   | | 3  | C    | m   | 5500   | | 4  | D    | f   | 500    | ``` 只用一个 SQL 查询,将 sex 字段反转。 ```html | id | name | sex | salary | |----|------|-----|--------| | 1  | A    | f   | 2500   | | 2  | B    | m   | 1500   | | 3  | C    | f   | 5500   | | 4  | D    | m   | 500    | ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS salary; CREATE TABLE salary ( id INT, NAME VARCHAR ( 100 ), sex CHAR ( 1 ), salary INT ); INSERT INTO salary ( id, NAME, sex, salary ) VALUES     ( '1', 'A', 'm', '2500' ),     ( '2', 'B', 'f', '1500' ),     ( '3', 'C', 'm', '5500' ),     ( '4', 'D', 'f', '500' ); ``` ## Solution ```sql UPDATE salary SET sex = CHAR ( ASCII(sex) ^ ASCII( 'm' ) ^ ASCII( 'f' ) ); ``` # 620. Not Boring Movies https://leetcode.com/problems/not-boring-movies/description/ ## Description ```html +---------+-----------+--------------+-----------+ |   id    | movie     |  description |  rating   | +---------+-----------+--------------+-----------+ |   1     | War       |   great 3D   |   8.9     | |   2     | Science   |   fiction    |   8.5     | |   3     | irish     |   boring     |   6.2     | |   4     | Ice song  |   Fantacy    |   8.6     | |   5     | House card|   Interesting|   9.1     | +---------+-----------+--------------+-----------+ ``` 查找 id 为奇数,并且 description 不是 boring 的电影,按 rating 降序。 ```html +---------+-----------+--------------+-----------+ |   id    | movie     |  description |  rating   | +---------+-----------+--------------+-----------+ |   5     | House card|   Interesting|   9.1     | |   1     | War       |   great 3D   |   8.9     | +---------+-----------+--------------+-----------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS cinema; CREATE TABLE cinema ( id INT, movie VARCHAR ( 255 ), description VARCHAR ( 255 ), rating FLOAT ( 2, 1 ) ); INSERT INTO cinema ( id, movie, description, rating ) VALUES     ( 1, 'War', 'great 3D', 8.9 ),     ( 2, 'Science', 'fiction', 8.5 ),     ( 3, 'irish', 'boring', 6.2 ),     ( 4, 'Ice song', 'Fantacy', 8.6 ),     ( 5, 'House card', 'Interesting', 9.1 ); ``` ## Solution ```sql SELECT     * FROM     cinema WHERE     id % 2 = 1     AND description != 'boring' ORDER BY     rating DESC; ``` # 596. Classes More Than 5 Students https://leetcode.com/problems/classes-more-than-5-students/description/ ## Description ```html +---------+------------+ | student | class      | +---------+------------+ | A       | Math       | | B       | English    | | C       | Math       | | D       | Biology    | | E       | Math       | | F       | Computer   | | G       | Math       | | H       | Math       | | I       | Math       | +---------+------------+ ``` 查找有五名及以上 student 的 class。 ```html +---------+ | class   | +---------+ | Math    | +---------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS courses; CREATE TABLE courses ( student VARCHAR ( 255 ), class VARCHAR ( 255 ) ); INSERT INTO courses ( student, class ) VALUES     ( 'A', 'Math' ),     ( 'B', 'English' ),     ( 'C', 'Math' ),     ( 'D', 'Biology' ),     ( 'E', 'Math' ),     ( 'F', 'Computer' ),     ( 'G', 'Math' ),     ( 'H', 'Math' ),     ( 'I', 'Math' ); ``` ## Solution ```sql SELECT     class FROM     courses GROUP BY     class HAVING     count( DISTINCT student ) >= 5; ``` # 182. Duplicate Emails https://leetcode.com/problems/duplicate-emails/description/ ## Description 邮件地址表: ```html +----+---------+ | Id | Email   | +----+---------+ | 1  | a@b.com | | 2  | c@d.com | | 3  | a@b.com | +----+---------+ ``` 查找重复的邮件地址: ```html +---------+ | Email   | +---------+ | a@b.com | +---------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS Person; CREATE TABLE Person ( Id INT, Email VARCHAR ( 255 ) ); INSERT INTO Person ( Id, Email ) VALUES     ( 1, 'a@b.com' ),     ( 2, 'c@d.com' ),     ( 3, 'a@b.com' ); ``` ## Solution ```sql SELECT     Email FROM     Person GROUP BY     Email HAVING     COUNT( * ) >= 2; ``` # 196. Delete Duplicate Emails https://leetcode.com/problems/delete-duplicate-emails/description/ ## Description 邮件地址表: ```html +----+---------+ | Id | Email   | +----+---------+ | 1  | a@b.com | | 2  | c@d.com | | 3  | a@b.com | +----+---------+ ``` 删除重复的邮件地址: ```html +----+------------------+ | Id | Email            | +----+------------------+ | 1  | john@example.com | | 2  | bob@example.com  | +----+------------------+ ``` ## SQL Schema 与 182 相同。 ## Solution 连接: ```sql DELETE p1 FROM     Person p1,     Person p2 WHERE     p1.Email = p2.Email     AND p1.Id > p2.Id ``` 子查询: ```sql DELETE FROM     Person WHERE     id NOT IN ( SELECT id FROM ( SELECT min( id ) AS id FROM Person GROUP BY email ) AS m ); ``` 应该注意的是上述解法额外嵌套了一个 SELECT 语句,如果不这么做,会出现错误:You can't specify target table 'Person' for update in FROM clause。以下演示了这种错误解法。 ```sql DELETE FROM     Person WHERE     id NOT IN ( SELECT min( id ) AS id FROM Person GROUP BY email ); ``` 参考:[pMySQL Error 1093 - Can't specify target table for update in FROM clause](https://stackoverflow.com/questions/45494/mysql-error-1093-cant-specify-target-table-for-update-in-from-clause) # 175. Combine Two Tables https://leetcode.com/problems/combine-two-tables/description/ ## Description Person 表: ```html +-------------+---------+ | Column Name | Type    | +-------------+---------+ | PersonId    | int     | | FirstName   | varchar | | LastName    | varchar | +-------------+---------+ PersonId is the primary key column for this table. ``` Address 表: ```html +-------------+---------+ | Column Name | Type    | +-------------+---------+ | AddressId   | int     | | PersonId    | int     | | City        | varchar | | State       | varchar | +-------------+---------+ AddressId is the primary key column for this table. ``` 查找 FirstName, LastName, City, State 数据,而不管一个用户有没有填地址信息。 ## SQL Schema ```sql DROP TABLE IF     EXISTS Person; CREATE TABLE Person ( PersonId INT, FirstName VARCHAR ( 255 ), LastName VARCHAR ( 255 ) ); DROP TABLE IF     EXISTS Address; CREATE TABLE Address ( AddressId INT, PersonId INT, City VARCHAR ( 255 ), State VARCHAR ( 255 ) ); INSERT INTO Person ( PersonId, LastName, FirstName ) VALUES     ( 1, 'Wang', 'Allen' ); INSERT INTO Address ( AddressId, PersonId, City, State ) VALUES     ( 1, 2, 'New York City', 'New York' ); ``` ## Solution 使用左外连接。 ```sql SELECT     FirstName,     LastName,     City,     State FROM     Person P     LEFT JOIN Address A     ON P.PersonId = A.PersonId; ``` # 181. Employees Earning More Than Their Managers https://leetcode.com/problems/employees-earning-more-than-their-managers/description/ ## Description Employee 表: ```html +----+-------+--------+-----------+ | Id | Name  | Salary | ManagerId | +----+-------+--------+-----------+ | 1  | Joe   | 70000  | 3         | | 2  | Henry | 80000  | 4         | | 3  | Sam   | 60000  | NULL      | | 4  | Max   | 90000  | NULL      | +----+-------+--------+-----------+ ``` 查找薪资大于其经理薪资的员工信息。 ## SQL Schema ```sql DROP TABLE IF     EXISTS Employee; CREATE TABLE Employee ( Id INT, NAME VARCHAR ( 255 ), Salary INT, ManagerId INT ); INSERT INTO Employee ( Id, NAME, Salary, ManagerId ) VALUES     ( 1, 'Joe', 70000, 3 ),     ( 2, 'Henry', 80000, 4 ),     ( 3, 'Sam', 60000, NULL ),     ( 4, 'Max', 90000, NULL ); ``` ## Solution ```sql SELECT     E1.NAME AS Employee FROM     Employee E1     INNER JOIN Employee E2     ON E1.ManagerId = E2.Id     AND E1.Salary > E2.Salary; ``` # 183. Customers Who Never Order https://leetcode.com/problems/customers-who-never-order/description/ ## Description Customers 表: ```html +----+-------+ | Id | Name  | +----+-------+ | 1  | Joe   | | 2  | Henry | | 3  | Sam   | | 4  | Max   | +----+-------+ ``` Orders 表: ```html +----+------------+ | Id | CustomerId | +----+------------+ | 1  | 3          | | 2  | 1          | +----+------------+ ``` 查找没有订单的顾客信息: ```html +-----------+ | Customers | +-----------+ | Henry     | | Max       | +-----------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS Customers; CREATE TABLE Customers ( Id INT, NAME VARCHAR ( 255 ) ); DROP TABLE IF     EXISTS Orders; CREATE TABLE Orders ( Id INT, CustomerId INT ); INSERT INTO Customers ( Id, NAME ) VALUES     ( 1, 'Joe' ),     ( 2, 'Henry' ),     ( 3, 'Sam' ),     ( 4, 'Max' ); INSERT INTO Orders ( Id, CustomerId ) VALUES     ( 1, 3 ),     ( 2, 1 ); ``` ## Solution 左外链接 ```sql SELECT     C.Name AS Customers FROM     Customers C     LEFT JOIN Orders O     ON C.Id = O.CustomerId WHERE     O.CustomerId IS NULL; ``` 子查询 ```sql SELECT     Name AS Customers FROM     Customers WHERE     Id NOT IN ( SELECT CustomerId FROM Orders ); ``` # 184. Department Highest Salary https://leetcode.com/problems/department-highest-salary/description/ ## Description Employee 表: ```html +----+-------+--------+--------------+ | Id | Name  | Salary | DepartmentId | +----+-------+--------+--------------+ | 1  | Joe   | 70000  | 1            | | 2  | Henry | 80000  | 2            | | 3  | Sam   | 60000  | 2            | | 4  | Max   | 90000  | 1            | +----+-------+--------+--------------+ ``` Department 表: ```html +----+----------+ | Id | Name     | +----+----------+ | 1  | IT       | | 2  | Sales    | +----+----------+ ``` 查找一个 Department 中收入最高者的信息: ```html +------------+----------+--------+ | Department | Employee | Salary | +------------+----------+--------+ | IT         | Max      | 90000  | | Sales      | Henry    | 80000  | +------------+----------+--------+ ``` ## SQL Schema ```sql DROP TABLE IF EXISTS Employee; CREATE TABLE Employee ( Id INT, NAME VARCHAR ( 255 ), Salary INT, DepartmentId INT ); DROP TABLE IF EXISTS Department; CREATE TABLE Department ( Id INT, NAME VARCHAR ( 255 ) ); INSERT INTO Employee ( Id, NAME, Salary, DepartmentId ) VALUES     ( 1, 'Joe', 70000, 1 ),     ( 2, 'Henry', 80000, 2 ),     ( 3, 'Sam', 60000, 2 ),     ( 4, 'Max', 90000, 1 ); INSERT INTO Department ( Id, NAME ) VALUES     ( 1, 'IT' ),     ( 2, 'Sales' ); ``` ## Solution 创建一个临时表,包含了部门员工的最大薪资。可以对部门进行分组,然后使用 MAX() 汇总函数取得最大薪资。 之后使用连接找到一个部门中薪资等于临时表中最大薪资的员工。 ```sql SELECT     D.NAME Department,     E.NAME Employee,     E.Salary FROM     Employee E,     Department D,     ( SELECT DepartmentId, MAX( Salary ) Salary FROM Employee GROUP BY DepartmentId ) M WHERE     E.DepartmentId = D.Id     AND E.DepartmentId = M.DepartmentId     AND E.Salary = M.Salary; ``` # 176. Second Highest Salary https://leetcode.com/problems/second-highest-salary/description/ ## Description ```html +----+--------+ | Id | Salary | +----+--------+ | 1  | 100    | | 2  | 200    | | 3  | 300    | +----+--------+ ``` 查找工资第二高的员工。 ```html +---------------------+ | SecondHighestSalary | +---------------------+ | 200                 | +---------------------+ ``` 没有找到返回 null 而不是不返回数据。 ## SQL Schema ```sql DROP TABLE IF     EXISTS Employee; CREATE TABLE Employee ( Id INT, Salary INT ); INSERT INTO Employee ( Id, Salary ) VALUES     ( 1, 100 ),     ( 2, 200 ),     ( 3, 300 ); ``` ## Solution 为了在没有查找到数据时返回 null,需要在查询结果外面再套一层 SELECT。 ```sql SELECT     ( SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT 1, 1 ) SecondHighestSalary; ``` # 177. Nth Highest Salary ## Description 查找工资第 N 高的员工。 ## SQL Schema 同 176。 ## Solution ```sql CREATE FUNCTION getNthHighestSalary ( N INT ) RETURNS INT BEGIN SET N = N - 1; RETURN ( SELECT ( SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT N, 1 ) ); END ``` # 178. Rank Scores https://leetcode.com/problems/rank-scores/description/ ## Description 得分表: ```html +----+-------+ | Id | Score | +----+-------+ | 1  | 3.50  | | 2  | 3.65  | | 3  | 4.00  | | 4  | 3.85  | | 5  | 4.00  | | 6  | 3.65  | +----+-------+ ``` 将得分排序,并统计排名。 ```html +-------+------+ | Score | Rank | +-------+------+ | 4.00  | 1    | | 4.00  | 1    | | 3.85  | 2    | | 3.65  | 3    | | 3.65  | 3    | | 3.50  | 4    | +-------+------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS Scores; CREATE TABLE Scores ( Id INT, Score DECIMAL ( 3, 2 ) ); INSERT INTO Scores ( Id, Score ) VALUES     ( 1, 3.5 ),     ( 2, 3.65 ),     ( 3, 4.0 ),     ( 4, 3.85 ),     ( 5, 4.0 ),     ( 6, 3.65 ); ``` ## Solution ```sql SELECT     S1.score,     COUNT( DISTINCT S2.score ) Rank FROM     Scores S1     INNER JOIN Scores S2     ON S1.score <= S2.score GROUP BY     S1.id ORDER BY     S1.score DESC; ``` # 180. Consecutive Numbers https://leetcode.com/problems/consecutive-numbers/description/ ## Description 数字表: ```html +----+-----+ | Id | Num | +----+-----+ | 1  |  1  | | 2  |  1  | | 3  |  1  | | 4  |  2  | | 5  |  1  | | 6  |  2  | | 7  |  2  | +----+-----+ ``` 查找连续出现三次的数字。 ```html +-----------------+ | ConsecutiveNums | +-----------------+ | 1               | +-----------------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS LOGS; CREATE TABLE LOGS ( Id INT, Num INT ); INSERT INTO LOGS ( Id, Num ) VALUES     ( 1, 1 ),     ( 2, 1 ),     ( 3, 1 ),     ( 4, 2 ),     ( 5, 1 ),     ( 6, 2 ),     ( 7, 2 ); ``` ## Solution ```sql SELECT     DISTINCT L1.num ConsecutiveNums FROM     Logs L1,     Logs L2,     Logs L3 WHERE L1.id = l2.id - 1     AND L2.id = L3.id - 1     AND L1.num = L2.num     AND l2.num = l3.num; ``` # 626. Exchange Seats https://leetcode.com/problems/exchange-seats/description/ ## Description seat 表存储着座位对应的学生。 ```html +---------+---------+ |    id   | student | +---------+---------+ |    1    | Abbot   | |    2    | Doris   | |    3    | Emerson | |    4    | Green   | |    5    | Jeames  | +---------+---------+ ``` 要求交换相邻座位的两个学生,如果最后一个座位是奇数,那么不交换这个座位上的学生。 ```html +---------+---------+ |    id   | student | +---------+---------+ |    1    | Doris   | |    2    | Abbot   | |    3    | Green   | |    4    | Emerson | |    5    | Jeames  | +---------+---------+ ``` ## SQL Schema ```sql DROP TABLE IF     EXISTS seat; CREATE TABLE seat ( id INT, student VARCHAR ( 255 ) ); INSERT INTO seat ( id, student ) VALUES     ( '1', 'Abbot' ),     ( '2', 'Doris' ),     ( '3', 'Emerson' ),     ( '4', 'Green' ),     ( '5', 'Jeames' ); ``` ## Solution 使用多个 union。 ```sql SELECT     s1.id - 1 AS id,     s1.student FROM     seat s1 WHERE     s1.id MOD 2 = 0 UNION SELECT     s2.id + 1 AS id,     s2.student FROM     seat s2 WHERE     s2.id MOD 2 = 1     AND s2.id != ( SELECT max( s3.id ) FROM seat s3 ) UNION SELECT     s4.id AS id,     s4.student FROM     seat s4 WHERE     s4.id MOD 2 = 1     AND s4.id = ( SELECT max( s5.id ) FROM seat s5 ) ORDER BY     id; ```