mirror of https://github.com/dunwu/db-tutorial.git
update codes
parent
8e9e519adb
commit
1923e6e39b
|
@ -3,19 +3,21 @@
|
|||
> [题库地址](https://leetcode.com/problemset/database/)
|
||||
|
||||
- **难度:简单**
|
||||
- [组合两个表](easy/combine-two-tables.sql)
|
||||
- [第二高的薪水](easy/second-highest-salary.sql)
|
||||
- [超过经理收入的员工](easy/employees-earning-more-than-their-managers.sql)
|
||||
- [查找重复的电子邮箱](easy/duplicate-emails.sql)
|
||||
- [从不订购的客户](easy/customers-who-never-order.sql)
|
||||
- [上升的温度](easy/rising-temperature.sql)
|
||||
- [大的国家](easy/big-countries.sql)
|
||||
- [超过5名学生的课](easy/classes-more-than-5-students.sql)
|
||||
- [有趣的电影](easy/not-boring-movies.sql)
|
||||
- [交换工资](easy/swap-salary.sql)
|
||||
- [组合两个表](easy/组合两个表.sql)
|
||||
- [第二高的薪水](easy/第二高的薪水.sql)
|
||||
- [超过经理收入的员工](easy/超过经理收入的员工.sql)
|
||||
- [查找重复的电子邮箱](easy/查找重复的电子邮箱.sql)
|
||||
- [从不订购的客户](easy/从不订购的客户.sql)
|
||||
- [删除重复的电子邮箱](easy/删除重复的电子邮箱.sql)
|
||||
- [上升的温度](easy/上升的温度.sql)
|
||||
- [大的国家](easy/大的国家.sql)
|
||||
- [超过5名学生的课](easy/超过5名学生的课.sql)
|
||||
- [有趣的电影](easy/有趣的电影.sql)
|
||||
- [交换工资](easy/交换工资.sql)
|
||||
- [重新格式化部门表](easy/重新格式化部门表.sql)
|
||||
- **难度:中等**
|
||||
- [第 N 高的薪水](normal/nth-highest-salary.sql)
|
||||
- [分数排名](normal/rank-scores.sql)
|
||||
- [连续出现的数字](normal/consecutive-numbers.sql)
|
||||
- [部门工资最高的员工](normal/department-highest-salary.sql)
|
||||
- [换座位](normal/exchange-seats.sql)
|
||||
- [第 N 高的薪水](normal/第N高的薪水.sql)
|
||||
- [分数排名](normal/分数排名.sql)
|
||||
- [连续出现的数字](normal/连续出现的数字.sql)
|
||||
- [部门工资最高的员工](normal/部门工资最高的员工.sql)
|
||||
- [换座位](normal/换座位.sql)
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
-- 查找重复的电子邮箱
|
||||
--
|
||||
-- 编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。
|
||||
--
|
||||
-- 示例:
|
||||
--
|
||||
-- +----+---------+
|
||||
-- | Id | Email |
|
||||
-- +----+---------+
|
||||
-- | 1 | a@b.com |
|
||||
-- | 2 | c@d.com |
|
||||
-- | 3 | a@b.com |
|
||||
-- +----+---------+
|
||||
-- 根据以上输入,你的查询应返回以下结果:
|
||||
--
|
||||
-- +---------+
|
||||
-- | Email |
|
||||
-- +---------+
|
||||
-- | a@b.com |
|
||||
-- +---------+
|
||||
-- 说明:所有电子邮箱都是小写字母。
|
||||
|
||||
SELECT Email
|
||||
FROM Person
|
||||
GROUP BY Email
|
||||
HAVING COUNT(*) > 1;
|
|
@ -1,40 +0,0 @@
|
|||
-- 超过经理收入的员工
|
||||
--
|
||||
-- Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。
|
||||
--
|
||||
-- +----+-------+--------+-----------+
|
||||
-- | Id | Name | Salary | ManagerId |
|
||||
-- +----+-------+--------+-----------+
|
||||
-- | 1 | Joe | 70000 | 3 |
|
||||
-- | 2 | Henry | 80000 | 4 |
|
||||
-- | 3 | Sam | 60000 | NULL |
|
||||
-- | 4 | Max | 90000 | NULL |
|
||||
-- +----+-------+--------+-----------+
|
||||
-- 给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。
|
||||
-- 在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。
|
||||
--
|
||||
-- +----------+
|
||||
-- | Employee |
|
||||
-- +----------+
|
||||
-- | Joe |
|
||||
-- +----------+
|
||||
|
||||
-- 以下 3 种解法,由上至下,处理速度越来越慢:
|
||||
-- 第 1 种查询
|
||||
SELECT e1.Name AS Employee
|
||||
FROM Employee e1
|
||||
INNER JOIN Employee e2
|
||||
ON e1.ManagerId = e2.Id AND e1.Salary > e2.Salary;
|
||||
|
||||
-- 第 2 种解法
|
||||
SELECT e1.Name AS Employee
|
||||
FROM Employee e1, Employee e2
|
||||
WHERE e1.ManagerId = e2.Id AND e1.Salary > e2.Salary;
|
||||
|
||||
-- 第 3 种查询
|
||||
SELECT e1.Name AS Employee
|
||||
FROM Employee e1
|
||||
WHERE
|
||||
e1.Salary > (SELECT e2.Salary
|
||||
FROM Employee e2
|
||||
WHERE e1.ManagerId = e2.Id);
|
|
@ -1,29 +0,0 @@
|
|||
-- 【交换工资】
|
||||
--
|
||||
-- 给定一个 salary表,如下所示,有m=男性 和 f=女性的值 。
|
||||
-- 交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求使用一个更新查询,并且没有中间临时表。
|
||||
--
|
||||
-- 例如:
|
||||
--
|
||||
-- | id | name | sex | salary |
|
||||
-- |----|------|-----|--------|
|
||||
-- | 1 | A | m | 2500 |
|
||||
-- | 2 | B | f | 1500 |
|
||||
-- | 3 | C | m | 5500 |
|
||||
-- | 4 | D | f | 500 |
|
||||
-- 运行你所编写的查询语句之后,将会得到以下表:
|
||||
--
|
||||
-- | id | name | sex | salary |
|
||||
-- |----|------|-----|--------|
|
||||
-- | 1 | A | f | 2500 |
|
||||
-- | 2 | B | m | 1500 |
|
||||
-- | 3 | C | f | 5500 |
|
||||
-- | 4 | D | m | 500 |
|
||||
|
||||
UPDATE SALARY
|
||||
SET SEX =
|
||||
CASE SEX
|
||||
WHEN 'm'
|
||||
THEN 'f'
|
||||
ELSE 'm'
|
||||
END;
|
|
@ -1,5 +1,7 @@
|
|||
-- 上升的温度
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/rising-temperature/
|
||||
--
|
||||
-- 给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。
|
||||
--
|
||||
-- +---------+------------------+------------------+
|
||||
|
@ -19,8 +21,23 @@
|
|||
-- | 4 |
|
||||
-- +----+
|
||||
|
||||
SELECT w1.Id
|
||||
FROM Weather w1, Weather w2
|
||||
WHERE w1.RecordDate = DATE_ADD(w2.RecordDate,interval
|
||||
1 DAY )
|
||||
AND w1.Temperature > w2.Temperature;
|
||||
CREATE TABLE weather (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
recorddate TIMESTAMP,
|
||||
temperature INT
|
||||
);
|
||||
|
||||
INSERT INTO weather (recorddate, temperature)
|
||||
VALUES (TIMESTAMP('2015-01-01'), 10);
|
||||
INSERT INTO weather (recorddate, temperature)
|
||||
VALUES (TIMESTAMP('2015-01-02'), 25);
|
||||
INSERT INTO weather (recorddate, temperature)
|
||||
VALUES (TIMESTAMP('2015-01-03'), 20);
|
||||
INSERT INTO weather (recorddate, temperature)
|
||||
VALUES (TIMESTAMP('2015-01-04'), 30);
|
||||
|
||||
-- 解题
|
||||
SELECT w1.id
|
||||
FROM weather w1, weather w2
|
||||
WHERE w1.recorddate = DATE_ADD(w2.recorddate, INTERVAL 1 DAY) AND w1.temperature > w2.temperature;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
-- 【交换工资】
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/swap-salary/
|
||||
--
|
||||
-- 给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。
|
||||
--
|
||||
-- 注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。
|
||||
--
|
||||
-- 例如:
|
||||
--
|
||||
-- | id | name | sex | salary |
|
||||
-- |----|------|-----|--------|
|
||||
-- | 1 | A | m | 2500 |
|
||||
-- | 2 | B | f | 1500 |
|
||||
-- | 3 | C | m | 5500 |
|
||||
-- | 4 | D | f | 500 |
|
||||
--
|
||||
-- 运行你所编写的更新语句之后,将会得到以下表:
|
||||
--
|
||||
-- | id | name | sex | salary |
|
||||
-- |----|------|-----|--------|
|
||||
-- | 1 | A | f | 2500 |
|
||||
-- | 2 | B | m | 1500 |
|
||||
-- | 3 | C | f | 5500 |
|
||||
-- | 4 | D | m | 500 |
|
||||
|
||||
CREATE TABLE IF NOT EXISTS salary (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name CHAR(5),
|
||||
sex CHAR(1),
|
||||
salary INT(10)
|
||||
);
|
||||
|
||||
INSERT INTO salary(name, sex, salary)
|
||||
VALUES ('A', 'm', 2500);
|
||||
INSERT INTO salary(name, sex, salary)
|
||||
VALUES ('B', 'f', 1500);
|
||||
INSERT INTO salary(name, sex, salary)
|
||||
VALUES ('C', 'm', 5500);
|
||||
INSERT INTO salary(name, sex, salary)
|
||||
VALUES ('D', 'f', 500);
|
||||
|
||||
-- 解题
|
||||
UPDATE salary
|
||||
SET sex =
|
||||
CASE sex
|
||||
WHEN 'm'
|
||||
THEN 'f'
|
||||
ELSE 'm'
|
||||
END;
|
||||
|
||||
SELECT *
|
||||
FROM salary;
|
|
@ -1,5 +1,7 @@
|
|||
-- 从不订购的客户
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/customers-who-never-order/
|
||||
--
|
||||
-- 某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
|
||||
--
|
||||
-- Customers 表:
|
||||
|
@ -29,12 +31,30 @@
|
|||
-- | Max |
|
||||
-- +-----------+
|
||||
|
||||
SELECT Name AS Customers
|
||||
FROM Customers c
|
||||
WHERE c.Id NOT IN (SELECT DISTINCT CustomerId
|
||||
FROM Orders);
|
||||
CREATE TABLE IF NOT EXISTS customers (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(20)
|
||||
);
|
||||
INSERT INTO customers(name)
|
||||
VALUES ('Joe');
|
||||
INSERT INTO customers(name)
|
||||
VALUES ('Henry');
|
||||
INSERT INTO customers(name)
|
||||
VALUES ('Sam');
|
||||
INSERT INTO customers(name)
|
||||
VALUES ('Max');
|
||||
|
||||
SELECT Name AS Customers
|
||||
FROM Customers
|
||||
INNER JOIN Orders
|
||||
ON Customers.Id != Orders.CustomerId;
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
customerid INT
|
||||
);
|
||||
INSERT INTO orders(customerid)
|
||||
VALUES (3);
|
||||
INSERT INTO orders(customerid)
|
||||
VALUES (1);
|
||||
|
||||
-- 方法一
|
||||
SELECT name AS customers
|
||||
FROM customers c
|
||||
WHERE c.id NOT IN (SELECT DISTINCT customerid
|
||||
FROM orders);
|
|
@ -0,0 +1,47 @@
|
|||
-- 删除重复的电子邮箱
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/delete-duplicate-emails/
|
||||
--
|
||||
-- 编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
|
||||
--
|
||||
-- +----+------------------+
|
||||
-- | Id | Email |
|
||||
-- +----+------------------+
|
||||
-- | 1 | john@example.com |
|
||||
-- | 2 | bob@example.com |
|
||||
-- | 3 | john@example.com |
|
||||
-- +----+------------------+
|
||||
-- Id 是这个表的主键。
|
||||
-- 例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:
|
||||
--
|
||||
-- +----+------------------+
|
||||
-- | Id | Email |
|
||||
-- +----+------------------+
|
||||
-- | 1 | john@example.com |
|
||||
-- | 2 | bob@example.com |
|
||||
-- +----+------------------+
|
||||
--
|
||||
--
|
||||
-- 提示:
|
||||
--
|
||||
-- 执行 SQL 之后,输出是整个 Person 表。
|
||||
-- 使用 delete 语句。
|
||||
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS person (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
email VARCHAR(32)
|
||||
);
|
||||
|
||||
INSERT INTO person (email)
|
||||
VALUES ('john@example.com');
|
||||
INSERT INTO person (email)
|
||||
VALUES ('bob@example.com');
|
||||
INSERT INTO person (email)
|
||||
VALUES ('john@example.com');
|
||||
|
||||
-- 解题
|
||||
DELETE p1
|
||||
FROM person p1, person p2
|
||||
WHERE p1.id > p2.id AND p1.email = p2.email;
|
|
@ -1,5 +1,7 @@
|
|||
-- 大的国家
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/big-countries/
|
||||
--
|
||||
-- 这里有张 World 表
|
||||
--
|
||||
-- +-----------------+------------+------------+--------------+---------------+
|
||||
|
@ -24,7 +26,35 @@
|
|||
-- | Algeria | 37100000 | 2381741 |
|
||||
-- +--------------+-------------+--------------+
|
||||
|
||||
SELECT NAME, POPULATION, AREA
|
||||
FROM World
|
||||
WHERE AREA > 3000000 OR POPULATION > 25000000;
|
||||
CREATE TABLE world (
|
||||
name VARCHAR(32) PRIMARY KEY,
|
||||
continent VARCHAR(32),
|
||||
area INT(10),
|
||||
population INT(20),
|
||||
gdp INT(20)
|
||||
);
|
||||
|
||||
INSERT INTO world
|
||||
VALUES ('Afghanistan', 'Asia', 652230, 25500100, 20343000);
|
||||
INSERT INTO world
|
||||
VALUES ('Albania', 'Europe', 28748, 2831741, 12960000);
|
||||
INSERT INTO world
|
||||
VALUES ('Algeria', 'Africa', 2381741, 37100000, 188681000);
|
||||
INSERT INTO world
|
||||
VALUES ('Andorra', 'Europe', 468, 78115, 3712000);
|
||||
INSERT INTO world
|
||||
VALUES ('Angola', 'Africa', 1246700, 20609294, 100990000);
|
||||
|
||||
-- 方法一
|
||||
SELECT name, population, area
|
||||
FROM world
|
||||
WHERE area > 3000000 OR population > 25000000;
|
||||
|
||||
-- 方法二
|
||||
SELECT name, population, area
|
||||
FROM world
|
||||
WHERE area > 3000000
|
||||
UNION
|
||||
SELECT name, population, area
|
||||
FROM world
|
||||
WHERE population > 25000000;
|
|
@ -26,7 +26,27 @@
|
|||
-- | 1 | War | great 3D | 8.9 |
|
||||
-- +---------+-----------+--------------+-----------+
|
||||
|
||||
USE db_tutorial;
|
||||
CREATE TABLE IF NOT EXISTS cinema (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
movie VARCHAR(20),
|
||||
description VARCHAR(20),
|
||||
rating DOUBLE
|
||||
);
|
||||
|
||||
INSERT INTO cinema(movie, description, rating)
|
||||
VALUES ('War', 'great 3D', 8.9);
|
||||
INSERT INTO cinema(movie, description, rating)
|
||||
VALUES ('Science', 'fiction', 8.5);
|
||||
INSERT INTO cinema(movie, description, rating)
|
||||
VALUES ('irish', 'boring', 6.2);
|
||||
INSERT INTO cinema(movie, description, rating)
|
||||
VALUES ('Ice song', 'Fantacy', 8.6);
|
||||
INSERT INTO cinema(movie, description, rating)
|
||||
VALUES ('House card', 'Interesting', 9.1);
|
||||
|
||||
-- 解题
|
||||
SELECT *
|
||||
FROM CINEMA
|
||||
WHERE DESCRIPTION != 'boring' AND ID % 2 = 1
|
||||
FROM cinema
|
||||
WHERE description != 'boring' AND id % 2 = 1
|
||||
ORDER BY rating DESC;
|
|
@ -0,0 +1,35 @@
|
|||
-- --------------------------------------------------------------------------------------
|
||||
-- 查找重复的电子邮箱
|
||||
-- @link https://leetcode-cn.com/problems/duplicate-emails/
|
||||
-- @author Zhang Peng
|
||||
-- @date 2020/02/29
|
||||
-- ----------------------------------------------------------------------------------------
|
||||
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS person (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
email VARCHAR(32)
|
||||
);
|
||||
|
||||
INSERT INTO person (email)
|
||||
VALUES ('a@b.com');
|
||||
INSERT INTO person (email)
|
||||
VALUES ('c@d.com');
|
||||
INSERT INTO person (email)
|
||||
VALUES ('a@b.com');
|
||||
|
||||
-- 方法一
|
||||
SELECT email
|
||||
FROM (
|
||||
SELECT email, COUNT(email) AS num
|
||||
FROM person
|
||||
GROUP BY email
|
||||
) AS statistic
|
||||
WHERE num > 1;
|
||||
|
||||
-- 方法二
|
||||
SELECT email
|
||||
FROM person
|
||||
GROUP BY email
|
||||
HAVING count(email) > 1;
|
|
@ -1,5 +1,7 @@
|
|||
-- 第二高的薪水
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/second-highest-salary/
|
||||
--
|
||||
-- 编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。
|
||||
--
|
||||
-- +----+--------+
|
||||
|
@ -17,7 +19,8 @@
|
|||
-- | 200 |
|
||||
-- +---------------------+
|
||||
|
||||
SELECT (SELECT DISTINCT SALARY
|
||||
FROM Employee
|
||||
ORDER BY SALARY DESC LIMIT 1,1)
|
||||
AS SecondHighestSalary;
|
||||
SELECT (SELECT DISTINCT salary
|
||||
FROM employee
|
||||
ORDER BY salary DESC
|
||||
LIMIT 1,1)
|
||||
AS secondhighestsalary;
|
|
@ -1,5 +1,7 @@
|
|||
-- 组合两个表
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/combine-two-tables/
|
||||
--
|
||||
-- 表1: Person
|
||||
--
|
||||
-- +-------------+---------+
|
||||
|
@ -29,7 +31,8 @@
|
|||
--
|
||||
-- FirstName, LastName, City, State
|
||||
|
||||
SELECT Person.FirstName, Person.LastName, Address.City, Address.State
|
||||
FROM Person
|
||||
LEFT JOIN Address
|
||||
ON Person.PersonId = Address.PersonId;
|
||||
|
||||
SELECT person.firstname, person.lastname, address.city, address.state
|
||||
FROM person
|
||||
LEFT JOIN address
|
||||
ON person.personid = address.personid;
|
|
@ -29,7 +29,34 @@
|
|||
-- Note:
|
||||
-- 学生在每个课中不应被重复计算。
|
||||
|
||||
SELECT CLASS
|
||||
FROM COURSES
|
||||
GROUP BY CLASS
|
||||
HAVING COUNT(DISTINCT STUDENT)>4;
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE courses (
|
||||
student VARCHAR(10) PRIMARY KEY,
|
||||
class VARCHAR(10)
|
||||
);
|
||||
|
||||
INSERT INTO courses
|
||||
VALUES ('A', 'Math');
|
||||
INSERT INTO courses
|
||||
VALUES ('B', 'English');
|
||||
INSERT INTO courses
|
||||
VALUES ('C', 'Math');
|
||||
INSERT INTO courses
|
||||
VALUES ('D', 'Biology');
|
||||
INSERT INTO courses
|
||||
VALUES ('E', 'Math');
|
||||
INSERT INTO courses
|
||||
VALUES ('F', 'Computer');
|
||||
INSERT INTO courses
|
||||
VALUES ('G', 'Math');
|
||||
INSERT INTO courses
|
||||
VALUES ('H', 'Math');
|
||||
INSERT INTO courses
|
||||
VALUES ('I', 'Math');
|
||||
|
||||
-- 解题
|
||||
SELECT class
|
||||
FROM courses
|
||||
GROUP BY class
|
||||
HAVING COUNT(DISTINCT student) >= 5;
|
|
@ -0,0 +1,100 @@
|
|||
# 重新格式化部门表
|
||||
#
|
||||
# @link https://leetcode-cn.com/problems/reformat-department-table/
|
||||
#
|
||||
# 部门表 Department:
|
||||
#
|
||||
# +---------------+---------+
|
||||
# | Column Name | Type |
|
||||
# +---------------+---------+
|
||||
# | id | int |
|
||||
# | revenue | int |
|
||||
# | month | varchar |
|
||||
# +---------------+---------+
|
||||
# (id, month) 是表的联合主键。
|
||||
# 这个表格有关于每个部门每月收入的信息。
|
||||
# 月份(month)可以取下列值 ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]。
|
||||
#
|
||||
#
|
||||
# 编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。
|
||||
#
|
||||
# 查询结果格式如下面的示例所示:
|
||||
#
|
||||
# Department 表:
|
||||
# +------+---------+-------+
|
||||
# | id | revenue | month |
|
||||
# +------+---------+-------+
|
||||
# | 1 | 8000 | Jan |
|
||||
# | 2 | 9000 | Jan |
|
||||
# | 3 | 10000 | Feb |
|
||||
# | 1 | 7000 | Feb |
|
||||
# | 1 | 6000 | Mar |
|
||||
# +------+---------+-------+
|
||||
#
|
||||
# 查询得到的结果表:
|
||||
# +------+-------------+-------------+-------------+-----+-------------+
|
||||
# | id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
|
||||
# +------+-------------+-------------+-------------+-----+-------------+
|
||||
# | 1 | 8000 | 7000 | 6000 | ... | null |
|
||||
# | 2 | 9000 | null | null | ... | null |
|
||||
# | 3 | null | 10000 | null | ... | null |
|
||||
# +------+-------------+-------------+-------------+-----+-------------+
|
||||
#
|
||||
# 注意,结果表有 13 列 (1个部门 id 列 + 12个月份的收入列)。
|
||||
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS department (
|
||||
id INT,
|
||||
revenue INT,
|
||||
month VARCHAR(20)
|
||||
);
|
||||
|
||||
INSERT INTO department
|
||||
VALUES (1, 8000, 'Jan');
|
||||
INSERT INTO department
|
||||
VALUES (2, 9000, 'Jan');
|
||||
INSERT INTO department
|
||||
VALUES (3, 10000, 'Feb');
|
||||
INSERT INTO department
|
||||
VALUES (1, 7000, 'Feb');
|
||||
INSERT INTO department
|
||||
VALUES (1, 6000, 'Mar');
|
||||
|
||||
-- 解题
|
||||
|
||||
SELECT id, revenue AS jan_revenue
|
||||
FROM department
|
||||
WHERE month = 'Jan';
|
||||
|
||||
SELECT id,
|
||||
SUM(CASE month WHEN 'Jan' THEN revenue END) jan_revenue,
|
||||
SUM(CASE month WHEN 'Feb' THEN revenue END) feb_revenue,
|
||||
SUM(CASE month WHEN 'Mar' THEN revenue END) mar_revenue,
|
||||
SUM(CASE month WHEN 'Apr' THEN revenue END) apr_revenue,
|
||||
SUM(CASE month WHEN 'May' THEN revenue END) may_revenue,
|
||||
SUM(CASE month WHEN 'Jun' THEN revenue END) jun_revenue,
|
||||
SUM(CASE month WHEN 'Jul' THEN revenue END) jul_revenue,
|
||||
SUM(CASE month WHEN 'Aug' THEN revenue END) aug_revenue,
|
||||
SUM(CASE month WHEN 'Sep' THEN revenue END) sep_revenue,
|
||||
SUM(CASE month WHEN 'Oct' THEN revenue END) oct_revenue,
|
||||
SUM(CASE month WHEN 'Nov' THEN revenue END) nov_revenue,
|
||||
SUM(CASE month WHEN 'Dec' THEN revenue END) dec_revenue
|
||||
FROM department
|
||||
GROUP BY id;
|
||||
|
||||
SELECT id,
|
||||
SUM(IF(month = 'Jan', revenue, NULL)) jan_revenue,
|
||||
SUM(IF(month = 'Feb', revenue, NULL)) feb_revenue,
|
||||
SUM(IF(month = 'Mar', revenue, NULL)) mar_revenue,
|
||||
SUM(IF(month = 'Apr', revenue, NULL)) apr_revenue,
|
||||
SUM(IF(month = 'May', revenue, NULL)) may_revenue,
|
||||
SUM(IF(month = 'Jun', revenue, NULL)) jun_revenue,
|
||||
SUM(IF(month = 'Jul', revenue, NULL)) jul_revenue,
|
||||
SUM(IF(month = 'Aug', revenue, NULL)) aug_revenue,
|
||||
SUM(IF(month = 'Sep', revenue, NULL)) sep_revenue,
|
||||
SUM(IF(month = 'Oct', revenue, NULL)) oct_revenue,
|
||||
SUM(IF(month = 'Nov', revenue, NULL)) nov_revenue,
|
||||
SUM(IF(month = 'Dec', revenue, NULL)) dec_revenue
|
||||
FROM department
|
||||
GROUP BY id;
|
|
@ -0,0 +1,75 @@
|
|||
-- 部门工资前三高的所有员工
|
||||
--
|
||||
-- Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId 。
|
||||
--
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | Id | Name | Salary | DepartmentId |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | 1 | Joe | 85000 | 1 |
|
||||
-- | 2 | Henry | 80000 | 2 |
|
||||
-- | 3 | Sam | 60000 | 2 |
|
||||
-- | 4 | Max | 90000 | 1 |
|
||||
-- | 5 | Janet | 69000 | 1 |
|
||||
-- | 6 | Randy | 85000 | 1 |
|
||||
-- | 7 | Will | 70000 | 1 |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- Department 表包含公司所有部门的信息。
|
||||
--
|
||||
-- +----+----------+
|
||||
-- | Id | Name |
|
||||
-- +----+----------+
|
||||
-- | 1 | IT |
|
||||
-- | 2 | Sales |
|
||||
-- +----+----------+
|
||||
-- 编写一个 SQL 查询,找出每个部门获得前三高工资的所有员工。例如,根据上述给定的表,查询结果应返回:
|
||||
--
|
||||
-- +------------+----------+--------+
|
||||
-- | Department | Employee | Salary |
|
||||
-- +------------+----------+--------+
|
||||
-- | IT | Max | 90000 |
|
||||
-- | IT | Randy | 85000 |
|
||||
-- | IT | Joe | 85000 |
|
||||
-- | IT | Will | 70000 |
|
||||
-- | Sales | Henry | 80000 |
|
||||
-- | Sales | Sam | 60000 |
|
||||
-- +------------+----------+--------+
|
||||
-- 解释:
|
||||
--
|
||||
-- IT 部门中,Max 获得了最高的工资,Randy 和 Joe 都拿到了第二高的工资,Will 的工资排第三。销售部门(Sales)只有两名员工,Henry 的工资最高,Sam 的工资排第二。
|
||||
|
||||
USE db_tutorial;
|
||||
CREATE TABLE IF NOT EXISTS employee (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(10),
|
||||
salary INT,
|
||||
departmentid INT
|
||||
);
|
||||
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Joe', 85000, 1);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Henry', 80000, 2);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Sam', 60000, 2);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Max', 90000, 1);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Janet', 69000, 1);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Randy', 85000, 1);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Will', 70000, 1);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS department (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(10)
|
||||
);
|
||||
|
||||
INSERT INTO department (name)
|
||||
VALUES ('IT');
|
||||
INSERT INTO department (name)
|
||||
VALUES ('Sale');
|
||||
|
||||
SELECT *
|
||||
FROM employee
|
||||
WHERE departmentid = 1 LIMIT ;
|
|
@ -1,52 +0,0 @@
|
|||
-- 部门工资最高的员工
|
||||
--
|
||||
-- Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。
|
||||
--
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | Id | Name | Salary | DepartmentId |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | 1 | Joe | 70000 | 1 |
|
||||
-- | 2 | Henry | 80000 | 2 |
|
||||
-- | 3 | Sam | 60000 | 2 |
|
||||
-- | 4 | Max | 90000 | 1 |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- Department 表包含公司所有部门的信息。
|
||||
--
|
||||
-- +----+----------+
|
||||
-- | Id | Name |
|
||||
-- +----+----------+
|
||||
-- | 1 | IT |
|
||||
-- | 2 | Sales |
|
||||
-- +----+----------+
|
||||
-- 编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max 在 IT 部门有最高工资,
|
||||
-- Henry 在 Sales 部门有最高工资。
|
||||
--
|
||||
-- +------------+----------+--------+
|
||||
-- | Department | Employee | Salary |
|
||||
-- +------------+----------+--------+
|
||||
-- | IT | Max | 90000 |
|
||||
-- | Sales | Henry | 80000 |
|
||||
-- +------------+----------+--------+
|
||||
|
||||
-- 第 1 种解法
|
||||
SELECT D.Name AS Department , E.Name AS Employee , E.Salary
|
||||
FROM
|
||||
Employee E,
|
||||
(SELECT DepartmentId, MAX(Salary) AS max
|
||||
FROM Employee
|
||||
GROUP BY DepartmentId) T,
|
||||
Department D
|
||||
WHERE E.DepartmentId = T.DepartmentId
|
||||
AND E.Salary = T.MAX
|
||||
AND E.DepartmentId = D.ID
|
||||
|
||||
-- 第 2 种解法
|
||||
SELECT D.Name AS Department , E.Name AS Employee , E.Salary
|
||||
FROM
|
||||
Employee E,
|
||||
Department D
|
||||
WHERE E.DepartmentId = D.ID
|
||||
AND (DepartmentId, Salary) IN
|
||||
(SELECT DepartmentId, MAX(Salary) AS max
|
||||
FROM Employee
|
||||
GROUP BY DepartmentId)
|
|
@ -1,30 +0,0 @@
|
|||
-- 第N高的薪水
|
||||
--
|
||||
-- 编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary)。
|
||||
--
|
||||
-- +----+--------+
|
||||
-- | Id | Salary |
|
||||
-- +----+--------+
|
||||
-- | 1 | 100 |
|
||||
-- | 2 | 200 |
|
||||
-- | 3 | 300 |
|
||||
-- +----+--------+
|
||||
-- 例如上述 Employee 表,n = 2 时,应返回第二高的薪水 200。如果不存在第 n 高的薪水,那么查询应返回 null。
|
||||
--
|
||||
-- +------------------------+
|
||||
-- | getNthHighestSalary(2) |
|
||||
-- +------------------------+
|
||||
-- | 200 |
|
||||
-- +------------------------+
|
||||
|
||||
CREATE FUNCTION getNthHighestSalary(N int) RETURNS INT
|
||||
BEGIN
|
||||
RETURN (
|
||||
SELECT DISTINCT Salary
|
||||
FROM Employee e
|
||||
WHERE
|
||||
N = (SELECT COUNT(DISTINCT Salary)
|
||||
FROM Employee
|
||||
WHERE Salary >= e.Salary)
|
||||
);
|
||||
END
|
|
@ -26,9 +26,30 @@
|
|||
-- | 3.50 | 4 |
|
||||
-- +-------+------+
|
||||
|
||||
SELECT Score, (
|
||||
SELECT COUNT(DISTINCT score)
|
||||
FROM Scores
|
||||
WHERE score >= s.score) AS Rank
|
||||
FROM Scores s
|
||||
ORDER BY Score DESC;
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS scores (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
score DOUBLE
|
||||
);
|
||||
|
||||
INSERT INTO scores (score)
|
||||
VALUES (3.50);
|
||||
INSERT INTO scores (score)
|
||||
VALUES (3.65);
|
||||
INSERT INTO scores (score)
|
||||
VALUES (4.00);
|
||||
INSERT INTO scores (score)
|
||||
VALUES (3.85);
|
||||
INSERT INTO scores (score)
|
||||
VALUES (4.00);
|
||||
INSERT INTO scores (score)
|
||||
VALUES (3.65);
|
||||
|
||||
SELECT count(DISTINCT b.score)
|
||||
FROM scores b;
|
||||
|
||||
SELECT a.score AS score,
|
||||
(SELECT count(DISTINCT b.score) FROM scores b WHERE b.score >= a.score) AS ranking
|
||||
FROM scores a
|
||||
ORDER BY a.score DESC;
|
|
@ -0,0 +1,48 @@
|
|||
-- 第N高的薪水
|
||||
--
|
||||
-- 编写一个 SQL 查询,获取 Employee 表中第 n 高的薪水(Salary)。
|
||||
--
|
||||
-- +----+--------+
|
||||
-- | Id | Salary |
|
||||
-- +----+--------+
|
||||
-- | 1 | 100 |
|
||||
-- | 2 | 200 |
|
||||
-- | 3 | 300 |
|
||||
-- +----+--------+
|
||||
-- 例如上述 Employee 表,n = 2 时,应返回第二高的薪水 200。如果不存在第 n 高的薪水,那么查询应返回 null。
|
||||
--
|
||||
-- +------------------------+
|
||||
-- | getNthHighestSalary(2) |
|
||||
-- +------------------------+
|
||||
-- | 200 |
|
||||
-- +------------------------+
|
||||
|
||||
USE db_tutorial;
|
||||
CREATE TABLE IF NOT EXISTS employee (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
salary INT
|
||||
);
|
||||
|
||||
INSERT INTO employee(salary)
|
||||
VALUES (100);
|
||||
INSERT INTO employee(salary)
|
||||
VALUES (200);
|
||||
INSERT INTO employee(salary)
|
||||
VALUES (300);
|
||||
|
||||
SELECT DISTINCT salary
|
||||
FROM employee e
|
||||
WHERE 1 = (SELECT COUNT(DISTINCT salary)
|
||||
FROM employee
|
||||
WHERE salary >= e.salary);
|
||||
|
||||
CREATE FUNCTION getNthHighestSalary(n INT) RETURNS INT
|
||||
BEGIN
|
||||
RETURN (
|
||||
SELECT DISTINCT salary
|
||||
FROM employee e
|
||||
WHERE n = (SELECT COUNT(DISTINCT salary)
|
||||
FROM employee
|
||||
WHERE salary >= e.salary)
|
||||
);
|
||||
END
|
|
@ -21,8 +21,30 @@
|
|||
-- | 1 |
|
||||
-- +-----------------+
|
||||
|
||||
SELECT DISTINCT l1.num AS ConsecutiveNums
|
||||
FROM Logs l1
|
||||
JOIN Logs l2 ON l1.id=l2.id-1
|
||||
JOIN Logs l3 ON l1.id=l3.id-2
|
||||
WHERE l1.num=l2.num AND l2.num=l3.num;
|
||||
USE db_tutorial;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
num INT
|
||||
);
|
||||
|
||||
INSERT INTO logs(num)
|
||||
VALUES (1);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (1);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (1);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (2);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (1);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (2);
|
||||
INSERT INTO logs(num)
|
||||
VALUES (2);
|
||||
|
||||
-- 解题
|
||||
SELECT DISTINCT (l1.num) AS 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;
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
-- 部门工资最高的员工
|
||||
--
|
||||
-- @link https://leetcode-cn.com/problems/department-highest-salary/
|
||||
--
|
||||
-- Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。
|
||||
--
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | Id | Name | Salary | DepartmentId |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- | 1 | Joe | 70000 | 1 |
|
||||
-- | 2 | Henry | 80000 | 2 |
|
||||
-- | 3 | Sam | 60000 | 2 |
|
||||
-- | 4 | Max | 90000 | 1 |
|
||||
-- +----+-------+--------+--------------+
|
||||
-- Department 表包含公司所有部门的信息。
|
||||
--
|
||||
-- +----+----------+
|
||||
-- | Id | Name |
|
||||
-- +----+----------+
|
||||
-- | 1 | IT |
|
||||
-- | 2 | Sales |
|
||||
-- +----+----------+
|
||||
-- 编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max 在 IT 部门有最高工资,
|
||||
-- Henry 在 Sales 部门有最高工资。
|
||||
--
|
||||
-- +------------+----------+--------+
|
||||
-- | Department | Employee | Salary |
|
||||
-- +------------+----------+--------+
|
||||
-- | IT | Max | 90000 |
|
||||
-- | Sales | Henry | 80000 |
|
||||
-- +------------+----------+--------+
|
||||
|
||||
USE db_tutorial;
|
||||
CREATE TABLE IF NOT EXISTS employee (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(10),
|
||||
salary INT,
|
||||
departmentid INT
|
||||
);
|
||||
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Joe', 70000, 1);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Henry', 80000, 2);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Sam', 60000, 2);
|
||||
INSERT INTO employee (name, salary, departmentid)
|
||||
VALUES ('Max', 90000, 1);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS department (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(10)
|
||||
);
|
||||
|
||||
INSERT INTO department (name)
|
||||
VALUES ('IT');
|
||||
INSERT INTO department (name)
|
||||
VALUES ('Sale');
|
||||
|
||||
SELECT *
|
||||
FROM employee
|
||||
WHERE departmentid, salary IN
|
||||
(SELECT departmentid, MAX(salary)
|
||||
FROM employee
|
||||
GROUP BY departmentid);
|
||||
|
||||
|
||||
-- 第 1 种解法
|
||||
SELECT d.name AS department, e.name AS employee, e.salary
|
||||
FROM employee e,
|
||||
(SELECT departmentid, MAX(salary) AS max
|
||||
FROM employee
|
||||
GROUP BY departmentid) t,
|
||||
department d
|
||||
WHERE e.departmentid = t.departmentid AND e.salary = t.max AND e.departmentid = d.id;
|
||||
|
||||
|
||||
-- 第 2 种解法
|
||||
SELECT d.name AS department, e.name AS employee, e.salary
|
||||
FROM employee e,
|
||||
department d
|
||||
WHERE e.departmentid = d.id AND
|
||||
(departmentid, salary) IN
|
||||
(SELECT departmentid, MAX(salary) AS max
|
||||
FROM employee
|
||||
GROUP BY departmentid);
|
Loading…
Reference in New Issue