数据库基本操作习题

题⽬⼀:

编写⼀个 SQL 查询,查找Person 表中所有重复的电⼦邮箱。
示例:
+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+
根据以上输⼊,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

CREATE TABLE Person(
	Id INT,
	Email VARCHAR(10)
);

INSERT INTO Person(Id,Email) 
VALUES 
(1,'[email protected]'),
(2,'[email protected]'),
(3,'[email protected]');

SELECT email FROM Person GROUP BY email 
HAVING COUNT(Email)>1;

题目二:

这⾥有张World 表
+-----------------+------------+------------+--------------+---------------+
| 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      |
+-----------------+------------+------------+--------------+---------------+
如果⼀个国家的⾯积超过300万平⽅公⾥,或者⼈⼝超过2500万,那么这个国家就是
⼤国家。
编写⼀个SQL查询,输出表中所有⼤国家的名称、⼈⼝和⾯积。
例如,根据上表,我们应该输出:
+--------------+-------------+--------------+
| name         | population  | area         |
+--------------+-------------+--------------+
| Afghanistan  | 25500100    | 652230       |
| Algeria      | 37100000    | 2381741      |
+--------------+-------------+--------------+
CREATE TABLE World(
	NAME VARCHAR(20),
	continent VARCHAR(10),
	AREA INT,
	population INT,
	gdp INT
);

INSERT INTO World(NAME,continent,AREA,population,gdp) 
VALUE
('Afghanistan','Asia',652230,25500100,20343000),
('Albania','Europe',28748,2831741,12960000),
('Albania','Africa',2381741,37100000,188681000),
('Andorra','Europe',468,78115,3712000),
('Angola','Africa',1246700,20609294,100990000);

SELECT NAME,population,AREA FROM world 
WHERE population>25000000 OR AREA>3000000;

题目三:

point 保存了⼀些点在 x 轴上的坐标,这些坐标都是整数。
写⼀个查询语句,找到这些点中最近两个点之间的距离。
+-----+
| x   |
+-----+
| -1  |
| 0   |
| 2   |
+-----+
最近距离显然是 '1' ,是点 '-1''0' 之间的距离。所以输出应该如下:
+---------+
| shortest|
+---------+
| 1       |
+---------+
注意:每个点都与其他点坐标不同,表 table 不会有重复坐标出现。
进阶:如果这些点在 x 轴上从左到右都有⼀个编号,输出结果时需要输出最近点对的
编号呢?
CREATE TABLE points(
	X INT
);

INSERT INTO points(X) VALUE (-1),(0),(2);

SELECT ABS(p1.x-p2.x) AS shortest FROM points p1,points p2 
WHERE p1.x<>p2.x ORDER BY shortest LIMIT 1;

题目四:

某城市开了⼀家新的电影院,吸引了很多⼈过来看电影。该电影院特别注意⽤户体验,专⻔有个 LED显示板做电影推荐,上⾯公布着影评和相关电影描述。

作为该电影院的信息部主管,您需要编写⼀个 SQL查询,找出所有影⽚描述为⾮boring (不⽆聊) 的并且 id 为奇数 的影⽚,结果请按等级 rating 排列。

例如,下表 cinema:
+---------+-----------+--------------+-----------+
| 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      | movie 	  | description  | rating 	 |
+---------+-----------+--------------+-----------+
| 5       | House card| Interesting  | 9.1   	 |
| 1       | War 	  | great 3D     | 8.9   	 |
+---------+-----------+--------------+-----------+
CREATE TABLE cinema(
	id INT,
	movie VARCHAR(10),
	description VARCHAR(10),
	rating DOUBLE(3,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);

SELECT * FROM cinema WHERE MOD (id,2)=1 AND description != 'boring'
ORDER BY rating DESC;

题目五:

在表 orders 中找到订单数最多客户对应的 customer_number 。

数据保证订单数最多的顾客恰好只有⼀位。

表 orders 定义如下:
+-------------------+-----------+
| Column 			| Type	    |
+-------------------+-----------+
| order_number 	    | int 		|
| customer_number   | int	    |
| order_date 	    | date 		|
| required_date	    | date 		|
| shipped_date 		| date 		|
| status 			| char(15)  |
| comment 			| char(200) |
+-------------------+-----------+

样例输⼊

+--------------+-----------------+------------+---------------+-------------+--------+---------+
| order_number | customer_number | order_date | required_date |shipped_date | status | comment |
+--------------+-----------------+------------+---------------+-------------+--------+---------+
| 1 		   | 1 				 | 2017-04-09 | 2017-04-13 	  | 2017-04-12  | Closed | 		   |
| 2 		   | 2 				 | 2017-04-15 | 2017-04-20 	  | 2017-04-18  | Closed |         |
| 3 		   | 3 				 | 2017-04-16 | 2017-04-25 	  | 2017-04-20  | Closed |         |
| 4 		   | 3 				 | 2017-04-18 | 2017-04-28 	  | 2017-04-25  | Closed |         |
+--------------+-----------------+------------+---------------+-------------+--------+---------+

样例输出:
+-----------------+
| customer_number |
+-----------------+
| 3 			  |
+-----------------+

解释:
customer_number 为 '3' 的顾客有两个订单,⽐顾客 '1' 或者 '2' 都要多,
因为他们只有⼀个订单
所以结果是该顾客的 customer_number ,也就是 3 。

进阶: 如果有多位顾客订单数并列最多,你能找到他们所有的 customer_number吗?

CREATE TABLE orders(
	order_number INT,
	customer_number INT,
	order_date DATE,
	required_date DATE,
	shipped_date DATE,
	STATUS CHAR(15),
	COMMENT CHAR(200)	
);


INSERT INTO orders(order_number,customer_number,order_date,required_date,shipped_date,STATUS)
VALUE
(1,1,'2017-04-09','2017-04-13','2017-04-12','Closed'),
(2,2,'2017-04-15','2017-04-20','2017-04-18','Closed'),
(3,3,'2017-04-16','2017-04-25','2017-04-20','Closed'),
(4,3,'2017-04-18','2017-04-28','2017-04-25','Closed');

SELECT customer_number,COUNT(customer_number) cou FROM orders
GROUP BY customer_number ORDER BY cou DESC LIMIT 1;

题目六

1: Person
+-------------+---------+
| Column Name | Type    |  
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId 是上表主键

表2: Address
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId 是上表主键

编写⼀个 SQL 查询,满⾜条件:⽆论 person 是否有地址信息,都需要基于上述两
表提供 person 的以下信息:

FirstName, LastName, City, State
CREATE TABLE Person(
	PersonId INT PRIMARY KEY,
	FirstName VARCHAR(10),
	LastName VARCHAR(10)
);

CREATE TABLE Address(
	AddressId INT PRIMARY KEY,
	PersonId INT,
	City VARCHAR(10),
	State VARCHAR(10)
);

SELECT FirstName,LastName,City,State 
FROM Person LEFT JOIN Address ON Person.PersonId=Address.PersonId;

题目七

给定⼀个 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 salary(
	id INT,
	NAME VARCHAR(10),
	sex VARCHAR(10),
	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);

UPDATE salary SET sex=
CASE sex WHEN 'm' THEN 'f' ELSE 'm' END;

题目八

给定表 customer ,⾥⾯保存了所有客户信息和他们的推荐⼈。
+------+------+-----------+
| id   | name | referee_id|
+------+------+-----------+
| 1    | Will | NULL	  |
| 2	   | Jane | NULL 	  |
| 3    | Alex | 2         |
| 4    | Bill | NULL 	  |
| 5    | Zack | 1 		  |
| 6    | Mark | 2 		  |
+------+------+-----------+

写⼀个查询语句,返回⼀个编号列表,列表中编号的推荐⼈的编号都 不是 2。
对于上⾯的示例数据,结果为:
+------+
| name |
+------+
| Will |
| Jane |
| Bill |
| Zack |
+------+
CREATE TABLE customer(
	id INT,
	NAME VARCHAR(10),
	referee_id INT
);

INSERT INTO customer(id,NAME,referee_id)
VALUES
(1,'Will',NULL),
(2,'Jane',NULL),
(3,'Alex',2),
(4,'Bill',NULL),
(5,'Zack',1),
(6,'Mark',2);

SELECT NAME FROM customer WHERE referee_id!=2 OR referee_id IS NULL;

题目九

ActorDirector 表:
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| actor_id    | int     |
| director_id | int     |
| timestamp   | int     |
+-------------+---------+
timestamp 是这张表的主键.
写⼀条SQL查询语句获取合作过⾄少三次的演员和导演的 id 对 (actor_id,director_id)

示例:
ActorDirector 表:
+-------------+-------------+-------------+
| actor_id    | director_id | timestamp   |
+-------------+-------------+-------------+
| 1           | 1           | 0           |
| 1           | 1           | 1           |
| 1           | 1           | 2           |
| 1           | 2           | 3           |
| 1           | 2           | 4           |
| 2           | 1           | 5           |
| 2           | 1           | 6           |
+-------------+-------------+-------------+

Result 表:
+-------------+-------------+
| actor_id 	  | director_id |
+-------------+-------------+
| 1           | 1           |
+-------------+-------------+
唯⼀的 id 对是 (1, 1),他们恰好合作了 3 次。
CREATE TABLE ActorDirector(
	actor_id INT,
	director_id INT,
	TIMESTAMP INT PRIMARY KEY
);

INSERT INTO ActorDirector(actor_id,director_id,TIMESTAMP) VALUES
(1,1,0),
(1,1,1),
(1,1,2),
(1,2,3),
(1,2,4),
(2,1,5),
(2,1,6);

SELECT actor_id,director_id FROM ActorDirector 
GROUP BY actor_id,director_id HAVING COUNT(*)>=3;

题目十

选出所有 bonus < 1000 的员⼯的 name 及其 bonus。
Employee 表单
+-------+--------+-----------+--------+
| empId | name   | supervisor| salary |
+-------+--------+-----------+--------+
| 1     | John   | 3 		 | 1000   |
| 2     | Dan    | 3		 | 2000   |
| 3     | Brad   | null 	 | 4000   |
| 4     | Thomas | 3 		 | 4000   |
+-------+--------+-----------+--------+
empId 是这张表单的主关键字

Bonus 表单
+-------+-------+
| empId | bonus |
+-------+-------+
| 2     | 500   |
| 4     | 2000  |
+-------+-------+
empId 是这张表单的主关键字

输出示例:
+-------+-------+
| name  | bonus |
+-------+-------+
| John  | null  |
| Dan   | 500   |
| Brad  | null  |
+-------+-------+
CREATE TABLE Employee(
	empId INT PRIMARY KEY,
	NAME VARCHAR(20),
	supervisor INT,
	salary INT
);

INSERT INTO Employee(empId,NAME,supervisor,salary) VALUES
(1,'John',3,1000),
(2,'Dan',3,2000),
(3,'Brad',NULL,4000),
(4,'Thomas',3,4000);

CREATE TABLE Bonus(
	empId INT PRIMARY KEY,
	bonus INT
);

INSERT INTO Bonus(empId,bonus) VALUES
(2,500),
(4,2000);

SELECT e.name,b.bonus FROM Employee e LEFT JOIN Bonus b
ON e.empId=b.empId WHERE IFNULL(bonus,0)<1000;

题目十一

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      |
+----------+
CREATE TABLE Employee(
	Id INT,
	NAME VARCHAR(10),
	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);

SELECT a.Name AS 'Employee' FROM Employee AS a,Employee AS b 
WHERE a.ManagerId=b.Id AND a.Salary>b.Salary;

题目十二

某⽹站包含两个表,Customers 表和 Orders 表。编写⼀个 SQL 查询,
找出所有从不订购任何东⻄的客户。

Customers 表:
+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Orders 表:
+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

例如给定上述表格,你的查询应返回:
+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+
CREATE TABLE Customers(
	Id INT,
	NAME VARCHAR(10)
); 

INSERT INTO Customers(Id,NAME) VALUES
(1,'Joe'),(2,'Henry'),(3,'Sam'),(4,'Max');


CREATE TABLE orders(
	Id INT,
	CustomerId INT
);

INSERT INTO orders(Id,CustomerId) VALUES
(1,3),(3,1);

SELECT customers.Name AS 'Customers' FROM customers 
WHERE customers.Id NOT IN (SELECT customerid FROM orders);

题目十三

⼀个⼩学⽣ Tim 的作业是判断三条线段是否能形成⼀个三⻆形。
然⽽,这个作业⾮常繁重,因为有⼏百组线段需要判断。
假设表 table1 保存了所有三条线段的三元组 x, y, z ,
你能帮 Tim 写⼀个查询语句,来判断每个三元组是否可以组成⼀个三⻆形吗?

+----+----+----+
| x  | y  | z  |
+----+----+----+
| 13 | 15 | 30 |
| 10 | 20 | 15 |
+----+----+----+

对于如上样例数据,你的查询语句应该返回如下结果:
+----+----+----+----------+
| x  | y  | z  | triangle |
+----+----+----+----------+
| 13 | 15 | 30 | No       |
| 10 | 20 | 15 | Yes      |
+----+----+----+----------+
CREATE TABLE table1(
	X INT,
	Y INT,NAME
	z INT
);

INSERT INTO table1(X,Y,z) VALUES
(13,15,30),(10,20,15);

SELECT *,IF( (X+Y)>z AND (Y+z)>X AND (X+z)>Y,'yes','no')AS triangle 
FROM table1;

题目十四

描述
给定 3 个表: salesperson, company, orders。
输出所有表 salesperson 中,没有向公司 'RED' 销售任何东⻄的销售员。

解释:

输⼊
表: salesperson
+----------+------+--------+-----------------+-----------+
| sales_id | name | salary | commission_rate | hire_date |
+----------+------+--------+-----------------+-----------+
| 1        | John | 100000 | 6               | 2006/4/1  |
| 2        | Amy  | 120000 | 5               | 2020/5/1  |
| 3        | Mrrk | 65000  | 12              | 2008/12/25|
| 4        | Pam  | 25000  | 25              | 2005/1/1  |
| 5 	   | Alex | 50000  | 10              | 2007/2/3  |
+----------+------+--------+-----------------+-----------+
表 salesperson 存储了所有销售员的信息。每个销售员都有⼀个销售员编号sales_id 和他的名字 name 。

表: company
+---------+--------+------------+
| com_id  | name   | city       |
+---------+--------+------------+
| 1       | RED    | Boston     |
| 2       | ORANGE | New York   |
| 3       | YELLOW | Boston     |
| 4       | GREEN  | Austin     |
+---------+--------+------------+
表 company 存储了所有公司的信息。每个公司都有⼀个公司编号 com_id 和它的名字 name 。

表: orders
+----------+------------+---------+----------+--------+
| order_id | order_date | com_id  | sales_id | amount |
+----------+------------+---------+----------+--------+
| 1        | 2014/1/1   | 3       | 4        | 100000 |
| 2        | 2014/2/1   | 4       | 5        | 5000   |
| 3        | 2014/3/1   | 1       | 1        | 50000  |
| 4        | 2014/4/1   | 1       | 4        | 25000  |
+----------+------------+---------+----------+--------+
表 orders 存储了所有的销售数据,包括销售员编号 sales_id 和公司编号com_id 。

输出
+------+
| name |
+------+
| Amy  |
| Mark |
| Alex |
+------+
解释
根据表 orders 中的订单 '3''4' ,容易看出只有 'John''Pam' 两个销售员曾经向公司 'RED' 销售过。
所以我们需要输出表 salesperson 中所有其他⼈的名字。
CREATE TABLE salesperson(
	sales_id INT,
	NAME VARCHAR(10),
	salary INT,
	commission_rate INT,
	hire_date DATE
);

CREATE TABLE company(
	com_id INT,
	NAME VARCHAR(10),
	city VARCHAR(10)
);

CREATE TABLE orders(
	order_id INT,
	order_date DATE,
	com_id INT,
	sales_id INT,
	amount INT
);

INSERT INTO salesperson VALUES
(1,'John',100000,6,'2006/4/1'),
(2,'Amy',120000,5,'2020/5/1'),
(3,'Mark',65000,2,'2008/12/25'),
(4,'Pam',25000,25,'2005/1/1'),
(5,'Alex',50000,10,'2007/2/3');

INSERT INTO company VALUES 
(1,'RED','Boston'),
(2,'ORANGE','New York'),
(3,'YELLOW','Boston'),
(4,'GREEN','Austin');

INSERT INTO orders VALUES 
(1,'2014/1/1',3,4,100000),
(2,'2014/2/1',4,5,5000),
(3,'2014/3/1',1,1,50000),
(4,'2014/4/1',1,4,25000);

SELECT NAME FROM salesperson WHERE NAME NOT IN
(SELECT s.name FROM orders o JOIN company c ON c.com_id=o.com_id
JOIN salesperson s ON s.sales_id=o.sales_id WHERE c.name='RED' GROUP BY s.name);

题目十五

编写⼀个 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  |
+----+------------------+
CREATE TABLE person(
	id INT PRIMARY KEY,
	Email VARCHAR(20)
);

INSERT INTO person VALUES
(1,'[email protected]'),
(2,'[email protected]'),
(3,'[email protected]');

DELETE p1 FROM person p1,person p2 WHERE p1.Email=p2.Email AND p1.id>p2.id;

题目十六

给定⼀个 Weather 表,编写⼀个 SQL 查询,来查找与之前(昨天的)⽇期相⽐温
度更⾼的所有⽇期的 Id。
+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
| 1       | 2015-01-01       | 10               |
| 2       | 2015-01-02       | 25               |
| 3       | 2015-01-03       | 20               |
| 4       | 2015-01-04       | 30               |
+---------+------------------+------------------+

例如,根据上述给定的 Weather 表格,返回如下 Id:
+----+
| Id |
+----+
| 2  |
| 4  |
+----+
CREATE TABLE Weather(
	id INT,
	RecordDate DATE,
	Temperature INT
);

INSERT INTO Weather VALUES 
(1,'2015-01-01',10),
(2,'2015-01-02',25),
(3,'2015-01-03',20),
(4,'2015-01-04',30);

SELECT w1.id FROM weather w1 ,weather w2 WHERE w1.recorddate - w2.recorddate = 1 AND w1.temperature > w2.temperature;

题目十七

表 my_numbers 的 num 字段包含很多数字,其中包括很多重复的数字。
你能写⼀个 SQL 查询语句,找到只出现过⼀次的数字中,最⼤的⼀个数字吗?
+---+
|num|
+---+
| 8 |
| 8 |
| 3 |
| 3 |
| 1 |
| 4 |
| 5 |
| 6 |
+---+

对于上⾯给出的样例数据,你的查询语句应该返回如下结果:
+---+
|num|
+---+
| 6 |
+---+
CREATE TABLE my_numbers(
	num INT
);

INSERT INTO my_numbers VALUES(8),(8),(3),(3),(1),(4),(5),(6);  

SELECT IFNULL(
(SELECT * FROM my_numbers GROUP BY num HAVING COUNT(*)=1 
ORDER BY num DESC LIMIT 1),NULL) AS num;

题目十八

有⼀个courses 表 ,有: student (学⽣) 和 class (课程)。
请列出所有超过或等于5名学⽣的课。

例如,表:
+---------+------------+
| student | class      |
+---------+------------+
| A       | Math       |
| B       | English    |
| C       | Math       |
| D       | Biology    |
| E       | Math       |
| F       | Computer   |
| G       | Math       |
| H       | Math       |
| I       | Math       |
+---------+------------+

应该输出:
+---------+
| class   |
+---------+
| Math    |
+---------+

Note:学⽣在每个课中不应被重复计算。
CREATE TABLE courses(
	student VARCHAR(10),
	class VARCHAR(10)
);

INSERT INTO courses VALUES
('A','Math'),('B','English'),('C','Math'),('D','biology'),
('E','Math'),('F','Computer'),('G','Math'),('H','Math'),('I','Math');

SELECT DISTINCT class FROM courses 
GROUP BY class HAVING COUNT(DISTINCT student)>=5;

题目十九

在 Facebook 或者 Twitter 这样的社交应⽤中,
⼈们经常会发好友申请也会收到其他⼈的好友申请。现在给如下两个表:
表: friend_request
+-----------+------------+------------+
| sender_id | send_to_id |request_date|
+-----------+------------+------------+
| 1         | 2          | 2016-06-01 |
| 1         | 3          | 2016-06-01 |
| 1         | 4          | 2016-06-01 |
| 2         | 3          | 2016-06-02 |
| 3         | 4          | 2016-06-09 |
+-----------+------------+------------+

表: request_accepted
+--------------+-------------+------------+
| requester_id | accepter_id |accept_date |
+--------------+-------------+------------+
| 1   		   | 2           | 2016-06-03 |
| 1   		   | 3           | 2016-06-08 |
| 2   		   | 3           | 2016-06-08 |
| 3   		   | 4           | 2016-06-09 |
| 3   		   | 4           | 2016-06-10 |
+--------------+-------------+------------+

写⼀个查询语句,求出好友申请的通过率,⽤ 2 位⼩数表示。
通过率由接受好友申请的数⽬除以申请总数。

对于上⾯的样例数据,你的查询语句应该返回如下结果。
+-----------+
|accept_rate|
+-----------+
| 0.80		|
+-----------+

注意:
通过的好友申请不⼀定都在表 friend_request 中。
在这种情况下,你只需要统计总的被通过的申请数(不管它们在不在原来的申请中),
并将它除以申请总数,得到通过率

⼀个好友申请发送者有可能会给接受者发⼏条好友申请,
也有可能⼀个好友申请会被通过好⼏次。
这种情况下,重复的好友申请只统计⼀次。

如果⼀个好友申请都没有,通过率为 0.00 。
解释: 总共有 5 个申请,其中 4 个是不重复且被通过的好友申请,所以成功率是0.80
CREATE TABLE friend_request(
	sender_id INT,
	send_to_id INT,
	request_date DATE
);

INSERT INTO friend_request VALUES
(1,2,'2016-06-01'),
(1,3,'2016-06-01'),
(1,4,'2016-06-01'),
(2,3,'2016-06-02'),
(3,4,'2016-06-09');

CREATE TABLE request_accepted(
	 requester_id INT,
	 accepter_id INT,
	 accept_date DATE
);

INSERT INTO request_accepted VALUES
(1,2,'2016-06-03'),
(1,3,'2016-06-08'),
(2,3,'2016-06-08'),
(3,4,'2016-06-09'),
(3,4,'2016-06-10'); 

SELECT (CASE 
	WHEN q1=0 THEN 
	ROUND(0,2) 
	ELSE ROUND(q1/q2,2) 
	END) accept_rate FROM
	(SELECT COUNT(*) q1 FROM 
	(SELECT requester_id,accepter_id 
	FROM request_accepted 
	GROUP BY requester_id,accepter_id)t1)t3,
	(SELECT COUNT(*) q2 FROM 
	(SELECT sender_id,send_to_id 
		FROM friend_request 
		GROUP BY sender_id,send_to_id)t2)t4;

题目二十

⼏个朋友来到电影院的售票处,准备预约连续空余座位。
你能利⽤表 cinema ,帮他们写⼀个查询语句,获取所有空余座位,
并将它们按照seat_id 排序后返回吗?
+---------+------+
| seat_id | free |
+---------+------+
| 1       | 1    |
| 2       | 0    |
| 3       | 1    |
| 4 	  | 1    |
| 5 	  | 1    |
+---------+------+

对于如上样例,你的查询语句应该返回如下结果。
+---------+
| seat_id |
+---------+
| 3       |
| 4       |
| 5       |
+---------+

注意:
seat_id 字段是⼀个⾃增的整数,free 字段是布尔类型
('1' 表示空余, '0'表示已被占据)。
连续空余座位的定义是⼤于等于 2 个连续空余的座位。
CREATE TABLE cinema(
	seat_id INT,
	free INT
);

INSERT INTO cinema VALUES(1,1),(2,0),(3,1),(4,1),(5,1);

SELECT 
	DISTINCT c1.seat_id
FRO

你可能感兴趣的:(java习题集,mysql,数据库)