- 大数据面试SQL题复习思路一网打尽!(文档见评论区)_哔哩哔哩_bilibili
- Hive SQL 大厂必考常用窗口函数及相关面试题
- 大数据面试SQL题-笔记01【运算符、条件查询、语法顺序、表连接】
- 大数据面试SQL题-笔记02【查询、连接、聚合函数】
目录
01、查询
01-1757. 可回收且低脂的产品
02-0584. 寻找用户推荐人
03-0595. 大的国家
04-1148. 文章浏览 I
05-1683. 无效的推文
02、连接
06-1378. 使用唯一标识码替换员工ID
07-1068. 产品销售分析 I
08-1581. 进店却未进行过交易的顾客
09-0197. 上升的温度
10-1661. 每台机器的进程平均运行时间
11-0577. 员工奖金
12-1280. 学生们参加各科测试的次数
13-0570. 至少有5名直接下属的经理
14-1934. 确认率
03、聚合函数
15-0620. 有趣的电影
16-1251. 平均售价
17-1075. 项目员工 I
01、查询
01-1757. 可回收且低脂的产品
# Write your MySQL query statement below
select product_id from Products where low_fats = 'Y' and recyclable = 'Y';
02-0584. 寻找用户推荐人
!= 与 <> 都是 不等于。
# Write your MySQL query statement below
select name from Customer where referee_id is null or referee_id != 2;
select name from Customer where referee_id is null or referee_id <> 2;
03-0595. 大的国家
# Write your MySQL query statement below
select name, population, area from World where area >=3000000 or population >= 25000000;
04-1148. 文章浏览 I
# Write your MySQL query statement below
select distinct author_id as id from Views where author_id = viewer_id order by author_id;
05-1683. 无效的推文
在MySQL中,你可以使用
LENGTH()
函数来获取字符串的长度。SELECT LENGTH('Hello, world!') AS string_length;
# Write your MySQL query statement below
select tweet_id from Tweets where length(content) > 15;
02、连接
06-1378. 使用唯一标识码替换员工ID
LEFT JOIN ... ON ...
# Write your MySQL query statement below
# select EmployeeUNI.unique_id, Employees.name from Employees join EmployeeUNI where Employees.id = EmployeeUNI.id;
SELECT
EmployeeUNI.unique_id, Employees.name
FROM
Employees
LEFT JOIN
EmployeeUNI
ON
Employees.id = EmployeeUNI.id;
07-1068. 产品销售分析 I
在 SQL 中,
INNER JOIN
和JOIN
是相同的,它们都用于连接两个或多个表,只返回满足连接条件的行。在实践中,它们通常可以互换使用,因为大多数 SQL 数据库都将它们视为等效的。INNER JOIN
是JOIN
的默认形式,因此在大多数情况下,简单地写JOIN
就足够了。
# Write your MySQL query statement below
select Product.product_name, Sales.year, Sales.price from Sales join Product on Sales.product_id = Product.product_id;
/* Write your T-SQL query statement below */
--写法一:
select p.product_name, s.year, s.price
from Sales s
inner join Product p
on s.product_id = p.product_id
--写法二:
select p.product_name, s.year, s.price
from Sales s
join Product p
using (product_id)
08-1581. 进店却未进行过交易的顾客
GROUP BY
语句将会按照customer_id
列进行分组,然后COUNT(*)
函数会计算每个分组中的行数,即每个客户ID的访问次数。
# Write your MySQL query statement below
select Visits.customer_id, count(Visits.customer_id) as count_no_trans
from Visits left join Transactions on Visits.visit_id = Transactions.visit_id
where Transactions.transaction_id is null -- where Transactions.amount is null
group by(Visits.customer_id)
-- order by count_no_trans desc
09-0197. 上升的温度
DATEDIFF()
是 MySQL 中用来计算两个日期之间的差异的函数。基本语法如下:
DATEDIFF(date1, date2)
date1
和date2
是你想要计算差异的两个日期。- 结果是
date1
和date2
之间的天数差。例如:
SELECT DATEDIFF('2024-04-15', '2024-04-10');
这个查询将返回
5
,因为 2024 年 4 月 10 日和 2024 年 4 月 15 日之间有 5 天。你也可以在表中使用列:
SELECT DATEDIFF(end_date, start_date) AS days_difference FROM orders;
这将计算
orders
表中每一行的end_date
和start_date
列之间的天数差,并将结果别名为days_difference
。
# Write your MySQL query statement below
select a.id from Weather as a, Weather as b
where datediff(a.recordDate, b.recordDate) = 1 and a.Temperature >b.Temperature;
select a.id from Weather as a inner join Weather as b
where datediff(a.recordDate, b.recordDate) = 1 and a.Temperature >b.Temperature;
10-1661. 每台机器的进程平均运行时间
# Write your MySQL query statement below
select a1.machine_id, round(avg(a2.timestamp -a1.timestamp ), 3) as processing_time
from Activity as a1 join Activity as a2 on
a1.machine_id = a2.machine_id and
a1.process_id = a2.process_id and
a1.activity_type = 'start' and a2.activity_type = 'end'
group by machine_id;
CAST()
是 MySQL 中用于将一个表达式转换为指定数据类型的函数。它的基本语法如下:
CAST(expression AS data_type)
expression
是你要转换的表达式或值。data_type
是你希望将表达式转换为的目标数据类型。例如,如果你有一个字符串类型的列,并且想将它转换为整数类型,你可以使用
CAST()
函数:
SELECT CAST('123' AS SIGNED);
这将返回整数
123
。或者,你可以将一个整数转换为字符串类型:
SELECT CAST(456 AS CHAR);
这将返回字符串
'456'
。
CAST()
函数可以用于多种数据类型之间的转换,包括整数、浮点数、日期等。
DECIMAL(10, 3)
是 MySQL 中用于定义精确数字数据类型的方式之一。在这个数据类型中,数字被存储为十进制数,并且允许指定总共有多少位数(包括小数点前后的数字)以及小数点后有多少位数。具体来说,
DECIMAL(10, 3)
定义了一个包含 10 位数字的数字,其中 3 位是小数位。这意味着这个数字可以存储从 -9999999.999 到 9999999.999 之间的数值,其中整数部分最多可以有 7 位数字,小数部分最多可以有 3 位数字。例如,
12345.678
是一个符合DECIMAL(10, 3)
定义的数字,而123456789.0123
则不符合,因为它的整数部分有 10 位数字,超出了限制。
-- 分为两层计算,第一层先按照machine_id和process_id分组,再计算组内最大值和最小值的差,就等同于end-start.
-- 第二层再按照machine_id分组,求平均.
select t2.machine_id, cast(avg(t2.tieminterval) as decimal(10, 3)) as processing_time
from
(select
machine_id, process_id, (max(Timestamp) - min(Timestamp)) as tieminterval
from
Activity
group by
machine_id,process_id) as t2
group by
t2.machine_id;
11-0577. 员工奖金
在 MySQL 中,可以使用以下几种表连接方式:
INNER JOIN:
INNER JOIN
返回两个表中共有的匹配行。LEFT JOIN (或 LEFT OUTER JOIN):
LEFT JOIN
返回左表中的所有行,以及右表中与左表中的行匹配的行。RIGHT JOIN (或 RIGHT OUTER JOIN):
RIGHT JOIN
返回右表中的所有行,以及左表中与右表中的行匹配的行。FULL JOIN (或 FULL OUTER JOIN):
FULL JOIN
返回左右两个表中的所有行,并且对于不匹配的行,会在结果集中填充 NULL 值。CROSS JOIN(JOIN):
CROSS JOIN
返回两个表的笛卡尔积,即左表中的每一行与右表中的每一行的组合。SELF JOIN:
SELF JOIN
是指对同一表进行连接操作,即连接表中的行与表中其他行进行比较。以上是 MySQL 中常见的表连接方式,可以根据需要选择合适的连接方式来检索数据。
# Write your MySQL query statement below
select Employee.name, Bonus.bonus from Employee left join Bonus on Employee.empId = Bonus.empId
where Bonus.bonus < 1000 or Bonus.bonus is null;
12-1280. 学生们参加各科测试的次数
解题思路:
- Student表和Subjects表进行笛卡尔积连接(Student JOIN Subjects)
- 在第一点的基础上拼接Examinations中的每个学生参加每门科目的数量。
- 根据案例可以看出,学生名单必须完整,在Examinations表中不存在则为0。所以使用左连接LEFT JOIN进行连接(Student JOIN Subjects LEFT JOIN Examinations)
- 注意排序不是按Examinations表进行排序的,因为存在NULL,下图就是第四个字段就是Examinations的student_id。
# Write your MySQL query statement below
SELECT
s.student_id,
s.student_name,
su.subject_name,
COUNT(e.subject_name) AS attended_exams
FROM
Students AS s
JOIN
Subjects AS su
LEFT JOIN
Examinations AS e
ON
e.student_id = s.student_id
AND
e.subject_name = su.subject_name
GROUP BY
s.student_id,
su.subject_name
ORDER BY
s.student_id,
su.subject_name;
13-0570. 至少有5名直接下属的经理
在 MySQL 中,
HAVING
子句通常与GROUP BY
子句一起使用,用于对分组后的结果进行筛选。HAVING
子句允许你基于聚合函数的结果来过滤结果集。例如,假设你有一个名为
sales
的表,其中包含销售数据,你想要找出每个销售人员的总销售额,并且只显示销售额大于 1000 的销售人员。你可以这样查询:
SELECT salesperson, SUM(amount) AS total_sales FROM sales GROUP BY salesperson HAVING total_sales > 1000;
在这个查询中,
SUM(amount)
是一个聚合函数,它计算每个销售人员的总销售额。然后,HAVING total_sales > 1000
筛选出总销售额大于 1000 的销售人员。总的来说,
HAVING
子句与WHERE
子句类似,但是HAVING
用于过滤分组后的结果,而WHERE
用于过滤未分组的原始数据。
# Write your MySQL query statement below
select Name
from (
select Manager.Name as Name, count(Report.Id) as cnt
from Employee as Manager join Employee as Report
on Manager.Id = Report.ManagerId
group by Manager.Id
) as ReportCount
where cnt >= 5;
select Manager.Name as Name
from Employee as Manager join Employee as Report
on Manager.Id = Report.ManagerId
group by Manager.Id
having count(Report.Id) >= 5;
select Employee.Name as Name
from (
select ManagerId as Id
from Employee
group by ManagerId
having count(Id) >= 5
) as Manager join Employee
on Manager.Id = Employee.Id;
14-1934. 确认率
if、ifnull
# Write your MySQL query statement below
select s.user_id, round(count(if(c.action='confirmed', 1, null))/count(*), 2) as confirmation_rate
from Signups s left join Confirmations c
on s.user_id = c.user_id
group by s.user_id;
SELECT
s.user_id,
ROUND(IFNULL(AVG(c.action='confirmed'), 0), 2) AS confirmation_rate
FROM
Signups AS s
LEFT JOIN
Confirmations AS c
ON
s.user_id = c.user_id
GROUP BY
s.user_id;
03、聚合函数
15-0620. 有趣的电影
mod(id,2)=1
来确定奇数 idMySQL 中判断奇数的 6 种方法:
- mod(x, 2) = 1 ,如果余数是 1 就是奇数。
- power(-1, x) = -1 , 如果结果是 -1 就是奇数
- x % 2 = 1 ,如果余数是 1 就是奇数。
- x & 1 = 1 ,如果是 1 就是奇数
- x regexp '[1, 3, 5, 7, 9]$' = 1 如果为 1 就是奇数
- x>>1<<1 != x 如果右移一位在左移一位不等于原值,就是奇数。
# Write your MySQL query statement below
select * from cinema where description != "boring" and id%2 != 0 order by rating desc;
16-1251. 平均售价
在 MySQL 中,
ROUND()
函数用于将数字值四舍五入到指定的小数位数。它的语法如下:ROUND(number, decimals)。
number
是要四舍五入的数字。decimals
是保留的小数位数,可以是负数来指定要四舍五入的位置。
# Write your MySQL query statement below
SELECT
product_id,
IFNULL(Round(SUM(sales) / SUM(units), 2), 0) AS average_price
FROM (
SELECT
Prices.product_id AS product_id,
Prices.price * UnitsSold.units AS sales,
UnitsSold.units AS units
FROM Prices
LEFT JOIN UnitsSold ON Prices.product_id = UnitsSold.product_id
AND (UnitsSold.purchase_date BETWEEN Prices.start_date AND Prices.end_date)
) T
GROUP BY product_id;
17-1075. 项目员工 I
MySQL是一种流行的关系型数据库管理系统,它提供了许多函数来执行各种操作。以下是你提到的几个函数的用法:
ROUND():
- 用途:ROUND函数用于将数值四舍五入到指定的小数位数。
- 语法:
ROUND(number, decimals)
number
: 要四舍五入的数值。decimals
: 指定的小数位数。- 示例:
SELECT ROUND(123.456, 2); -- 返回 123.46 SELECT ROUND(123.456); -- 返回 123
AVG():
- 用途:AVG函数用于计算某列的平均值。
- 语法:
AVG(expression)
expression
: 要计算平均值的列或表达式。- 示例:
SELECT AVG(column_name) FROM table_name; -- 计算列的平均值 SELECT AVG(5 + 5) FROM table_name; -- 计算表达式的平均值
SUM():
- 用途:SUM函数用于计算某列中所有值的总和。
- 语法:
SUM(expression)
expression
: 要计算总和的列或表达式。- 示例:
SELECT SUM(column_name) FROM table_name; -- 计算列值的总和 SELECT SUM(5 + 5) FROM table_name; -- 计算表达式值的总和
# Write your MySQL query statement below
SELECT
project_id,
ROUND(AVG(e.experience_years), 2) AS average_years
FROM
Project as p
LEFT JOIN
Employee as e
ON
p.employee_id = e.employee_id
GROUP BY
p.project_id;