MySQL语句练习(一)(附带mysql函数)

本文精选了一系列SQL查询案例,涵盖数据筛选、聚合、联表、子查询等核心技能,旨在帮助读者掌握高效的数据处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ADDTIME (date2 ,time_interval )	将time_interval加到date2
CURRENT_DATE (  )	当前日期
CURRENT_TIME (  )	当前时间
CURRENT_TIMESTAMP (  )	当前时间戳
DATE (datetime )	返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type )	在date2中加上日期或时间
DATE_SUB (date2 , INTERVAL d_value d_type )	在date2上减去一个时间
DATEDIFF (date1 ,date2 )	两个日期差
NOW (  )	当前时间
YEAR|Month|Day(datetime )	年月日
CHARSET(str)	返回字串字符集
CONCAT (string2  [,... ])	连接字串
INSTR (string ,substring )	返回substring在string中出现的位置,没有返回0
UCASE (string2 )	转换成大写
LCASE (string2 )	转换成小写
LEFT (string2 ,length )	从string2中的左边起取length个字符
LENGTH (string )	string长度
REPLACE (str ,search_str ,replace_str )	在str中用replace_str替换search_str
STRCMP (string1 ,string2 )	逐字符比较两字串大小,
SUBSTRING (str , position  [,length ])	从str的position开始,取length个字符
LTRIM (string2 ) RTRIM (string2 )  trim	去除前端空格或后端空格
ABS (number2 )	绝对值
BIN (decimal_number )	十进制转二进制
CEILING (number2 )	向上取整
CONV(number2,from_base,to_base)	进制转换
FLOOR (number2 )	向下取整
FORMAT (number,decimal_places )	保留小数位数
HEX (DecimalNumber )	转十六进制
LEAST (number , number2  [,..])	求最小值
MOD (numerator ,denominator )	求余
RAND([seed])	RAND([seed])

题目一

编写一个 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(20)
);
INSERT INTO Person VALUES(1,‘a@b.com’);
INSERT INTO Person VALUES(2,‘c@b.com’);
INSERT INTO Person VALUES(3,‘a@b.com’);
SELECT DISTINCT c1.Email FROM person c1,person c2 WHERE c1.Email=c2.Email AND c2.id!=c1.id;
SELECT Email FROM person  GROUP BY Email HAVING COUNT(*)>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(20),
AREA INT(10),
population INT(10),
gdp INT(10)
);

INSERT INTO World VALUES(‘Afghanistan’,‘Asia’,652230,25500100,2034300);
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 c1 WHERE c1.area>3000000 OR population > 25000000; 

题目三

表 point 保存了一些点在 x 轴上的坐标,这些坐标都是整数。

写一个查询语句,找到这些点中最近两个点之间的距离。

| x |

|-----|

| -1 |

| 0 |

| 2 |

最近距离显然是 ‘1’ ,是点 ‘-1’ 和 ‘0’ 之间的距离。所以输出应该如下:

| shortest|

|---------|

| 1 |

注意:每个点都与其他点坐标不同,表 table 不会有重复坐标出现。

进阶:如果这些点在 x 轴上从左到右都有一个编号,输出结果时需要输出最近点对的编号呢?

答案:
CREATE TABLE POINT(
X INT
);
INSERT INTO POINT VALUES(-1);
INSERT INTO POINT VALUES(0);
INSERT INTO POINT VALUES(2);
 SELECT MIN(ABS(x1.x-x2.x)) AS shortest FROM POINT x1,POINT x2 WHERE x1.x!=x2.x;

题目四

某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 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
);
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 description!='boring' AND id%2=1
ORDER BY rating DESC;

题目五

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

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

表 orders 定义如下:

| Column | Type |

|-------------------|-----------|

| order_number (PK) | 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 。

答案:
CREATE TABLE orders(
order_number INT,
customer_number INT,
order_date DATE,
required_date DATE,
shipped_date DATE,
STATUS VARCHAR(15),
COMMENT VARCHAR(200)
);
INSERT INTO orders(order_number,customer_number,order_date,required_date,shipped_date,STATUS,COMMENT)VALUES
(1,1,‘2017-04-09’,‘2017-04-13’,’ 2017-04-12’,‘Closed’,NULL),
(2,2,‘2017-04-15’,‘2017-04-20’,’ 2017-04-18’,‘Closed’,NULL),
(3,3,‘2017-04-16’,‘2017-04-25’,’ 2017-04-20’,‘Closed’,NULL),
(4,3,‘2017-04-18’,‘2017-04-28’,’ 2017-04-25’,‘Closed’,NULL);
 
 
 SELECT customer_number  FROM orders GROUP BY customer_number ORDER BY COUNT(customer_number) DESC LIMIT 1
 

题目六

表1: Person

±------------±--------+

| 列名 | 类型 |

±------------±--------+

| PersonId | int |

| FirstName | varchar |

| LastName | varchar |

±------------±--------+

PersonId 是上表主键

表2: Address

±------------±--------+

| 列名 | 类型 |

±------------±--------+

| AddressId | int |

| PersonId | int |

| City | varchar |

| State | varchar |

±------------±--------+

AddressId 是上表主键

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

FirstName, LastName, City, State

答案:
CREATE TABLE Person(
PersonId INT PRIMARY KEY AUTO_INCREMENT,
FirstName VARCHAR(20),
LastName VARCHAR(20)
);

CREATE TABLE Address(
AddressId INT PRIMARY KEY AUTO_INCREMENT,
PersonId INT,
City VARCHAR(20),
State VARCHAR(20)
)
INSERT INTO Person 
VALUES (1,'张','三'),(2,'李','四')

INSERT INTO Address
VALUES(1,2,'上海','一线'),(2,1,'北京','一线')
 SELECT c1.FirstName,c1.LastName,c2.City,c2.State FROM person c1 LEFT JOIN Address c2 ON c1.PersonId=c2.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’,‘f’,2500),(2,‘B’,‘m’,1500),
(3,‘C’,‘f’,5500),(4,'D','m',500);
 
UPDATE salary SET sex = IF(sex = 'm', 'f','m');
UPDATE salary SET sex  = (CASE WHEN sex = '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 |

±-----+

答案:
SELECT NAME FROM customer WHERE referee_id IS NULL  OR referee_id!=2 CREATE TABLE customer(
id INT,
NAME VARCHAR(20),
referee_id INT
);
INSERT INTO customer
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 IS NULL  OR referee_id!=2  

题目九

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 AUTO_INCREMENT
);
SELECT *FROM ActorDirector
INSERT INTO ActorDirector VALUES
(1,1,1),(1,1,2),(1,1,3),(1,2,4),(1,2,5),(2,1,6),(2,1,7);
 
SELECT actor_id,dir_id FROM actordirector GROUP BY actor_id ,dir_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 AUTO_INCREMENT,
NAME VARCHAR(10),
supervisor INT,
salary INT
);
CREATE TABLE Bonus(
empId INT PRIMARY KEY AUTO_INCREMENT,
bonus INT
);
INSERT INTO Employee(NAME,supervisor,salary)
VALUES
(‘join’,3,1000),
(‘Dan’,3,2000),
(‘Brad’,NULL ,4000),
(‘Thomas’,3,4000)
SELECT *FROM Employee
INSERT INTO Bonus
VALUES
(2,500),
(4,2000);
SELECT a.name,bonus FROM employee a LEFT JOIN bonus b ON a.empid=b.empid WHERE b.bonus<1000 OR b.bonus IS NULL 

(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 PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
salary INT,
ManagerId INT
);
INSERT INTO Employee(NAME,salary,ManagerId)VALUES
(‘Joe’,70000,3),
(‘Hernry’,80000,4),
(‘Sam’,60000,NULL),
(‘Max’,90000,NULL)
 
SELECT a.name AS 'Employee' FROM employee a JOIN employee b WHERE a.ManagerId = b.Id AND a.salary>b.salary

SELECT NAME AS 'Employee' FROM employee e1 WHERE salary > (SELECT salary FROM employee e2 WHERE id = e1.ManagerId)

题目十二

某网站包含两个表,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 PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10)
);
 
CREATE TABLE Orders(
id INT PRIMARY KEY AUTO_INCREMENT,
cusid INT
);
INSERT INTO Customers(NAME) VALUES(‘Joe’),(‘Henry’),(‘Sam’),(‘Max’)
INSERT INTO Orders(cusid) VALUES(3),(1)
SELECT a.name FROM customers a LEFT JOIN orders1 b ON a.id=b.cusid WHERE cusid IS NULL 

SELECT c.name FROM customers c WHERE id NOT IN (SELECT cusid FROM orders1 o WHERE c.id = o.cusid)
 

题目十三

一个小学生 Tim 的作业是判断三条线段是否能形成一个三角形。

然而,这个作业非常繁重,因为有几百组线段需要判断。

假设表 table 保存了所有三条线段的三元组 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 work(
X INT,
Y INT,
z INT
);
SELECT *,IF( X+Y>z AND X+z>Y AND Y+z>X , 'Yes','No') AS triangle
FROM work

题目十四

描述

给定 3 个表: salesperson, company, orders。

输出所有表 salesperson 中,没有向公司 ‘RED’ 销售任何东西的销售员。

解释

输入

表: salesperson

±---------±-----±-------±----------------±----------+

| sales_id | name | salary | commission_rate | hire_date |

±---------±-----±-------±----------------±----------+

| 1 | John | 100000 | 6 | 4/1/2006 |

| 2 | Amy | 120000 | 5 | 5/1/2010 |

| 3 | Mark | 65000 | 12 | 12/25/2008|

| 4 | Pam | 25000 | 25 | 1/1/2005 |

| 5 | Alex | 50000 | 10 | 2/3/2007 |

±---------±-----±-------±----------------±----------+

表 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 | 1/1/2014 | 3 | 4 | 100000 |

| 2 | 2/1/2014 | 4 | 5 | 5000 |

| 3 | 3/1/2014 | 1 | 1 | 50000 |

| 4 | 4/1/2014 | 1 | 4 | 25000 |

±---------±---------±--------±---------±-------+

表 orders 存储了所有的销售数据,包括销售员编号 sales_id 和公司编号 com_id 。

输出

±-----+

| name |

±-----+

| Amy |

| Mark |

| Alex |

±-----+

解释

根据表 orders 中的订单 ‘3’ 和 ‘4’ ,容易看出只有 ‘John’ 和 ‘Pam’ 两个销售员曾经向公司 ‘RED’ 销售过。

所以我们需要输出表 salesperson 中所有其他人的名字。

CREATE TABLE saleperson(
sales_id INT,
NAME VARCHAR(20),
salary INT,
commission_rate INT,
hire_date VARCHAR(20)
)
CREATE TABLE company(
com_id INT,
NAME VARCHAR(20),
city VARCHAR(20)
)
CREATE TABLE orders (
order_id INT,
order_date VARCHAR(20),
com_id INT,
sales_id INT,
amount INT
)
答案:
SELECT NAME FROM saleperson WHERE sales_id NOT IN (
    SELECT sales_id FROM orders WHERE com_id IN (   
	   SELECT com_id FROM company WHERE NAME ='RED'   
    )
)

题目十五

编写一个 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,
Email VARCHAR(30)
)

INSERT INTO Person VALUES
(1,‘john@example.com’),
(2,‘bob@example.com’),
(3,‘john@example.com’)
 
DELETE 
    a
FROM
    Person a,
    Person b
WHERE
    a.Email = b.Email AND a.Id > b.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 id FROM weather a WHERE Temperature > (
	SELECT Temperature FROM weather b WHERE a.RecordDate=b.RecordDate+1
)
SELECT
	a.id
FROM 
	weather a,
	weather b
WHERE
	a.RecordDate=b.RecordDate+1 AND a.Temperature>b.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 * FROM my_numbers GROUP BY num HAVING COUNT(*)=1 ORDER BY num DESC LIMIT 1

题目十八

有一个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 class FROM courses GROUP BY class HAVING COUNT(*)>=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
)

CREATE TABLE request_accepted(
requester_id INT,
accepter_id INT,
accept_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’)
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(
FORMAT( 
(
	(SELECT COUNT(t.num) FROM (SELECT COUNT(*) num FROM request_accepted GROUP BY requester_id,accepter_id ) t )
	/
	(SELECT COUNT(a.num) FROM (SELECT COUNT(*) num FROM friend_request  GROUP BY sender_id,send_to_id) a )
),2
)
) AS 'accept_rate'
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值