MySQL实战面试题(附案例答案+建表语句+模拟数据+案例深度解析),练完直接碾压面试官

知识点思维导图

在这里插入图片描述

案例1

建表语句与模拟数据

用户表 users

CREATE TABLE users (  id INT AUTO_INCREMENT PRIMARY KEY,  username VARCHAR(50) NOT NULL,  email VARCHAR(100) NOT NULL UNIQUE,  signup_date DATE NOT NULL  
);  INSERT INTO users (username, email, signup_date) VALUES  
('Alice', 'alice@example.com', '2023-01-01'),  
('Bob', 'bob@example.com', '2023-02-15'),  
('Charlie', 'charlie@example.com', '2023-01-10'),  
('David', 'david@example.com', '2023-03-01');

订单表 orders

CREATE TABLE orders (  id INT AUTO_INCREMENT PRIMARY KEY,  user_id INT,  order_date DATE NOT NULL,  amount DECIMAL(10, 2) NOT NULL,  FOREIGN KEY (user_id) REFERENCES users(id)  
);  INSERT INTO orders (user_id, order_date, amount) VALUES  
(1, '2023-01-15', 100.00),  
(2, '2023-02-20', 150.00),  
(1, '2023-03-05', 75.00),  
(3, '2023-01-20', 90.00);

题目一:查询2023年1月注册的所有用户。

答案:

SELECT * FROM users WHERE YEAR(signup_date) = 2023 AND MONTH(signup_date) = 1;

解析:

使用YEAR()和MONTH()函数从signup_date字段中提取年份和月份,并匹配给定的条件。

题目二:查询每个用户的订单总数和总金额。

答案:

SELECT u.username, COUNT(o.id) AS order_count, SUM(o.amount) AS total_amount  
FROM users u  
LEFT JOIN orders o ON u.id = o.user_id  
GROUP BY u.id, u.username;

解析:

通过左连接users和orders表,按用户分组,并使用COUNT()和SUM()函数计算每个用户的订单数量和总金额。

题目三:查询没有下过订单的用户。

答案:

SELECT * FROM users  
WHERE id NOT IN (SELECT DISTINCT user_id FROM orders);

或者

SELECT * FROM users  
LEFT JOIN orders ON users.id = orders.user_id  
WHERE orders.id IS NULL;

解析:

第一种方法使用子查询找出所有下过订单的用户ID,然后在主查询中排除这些ID。第二种方法通过左连接users和orders表,并检查orders.id是否为NULL来找出没有订单的用户。

题目四:查询2023年2月订单金额最高的用户及其订单金额。

答案:

SELECT u.username, MAX(o.amount) AS max_amount  
FROM orders o  
JOIN users u ON o.user_id = u.id  
WHERE YEAR(o.order_date) = 2023 AND MONTH(o.order_date) = 2  
GROUP BY u.id, u.username;

注意:这个查询实际上返回的是每个符合条件用户的最大订单金额,但题目表述可能暗示只找一个用户。如果需要确切地只找一个用户(如果有多个用户并列最高),则可能需要更复杂的查询或使用窗口函数(如果MySQL版本支持)。

解析:

首先通过日期条件筛选出2023年2月的订单,然后按用户分组,并使用MAX()函数找出每个用户的最大订单金额。

案例2

建表语句与模拟数据

商品表 products

CREATE TABLE products (  product_id INT AUTO_INCREMENT PRIMARY KEY,  name VARCHAR(100) NOT NULL,  category VARCHAR(50) NOT NULL,  price DECIMAL(10, 2) NOT NULL  
);  INSERT INTO products (name, category, price) VALUES  
('Laptop', 'Electronics', 999.99),  
('Smartphone', 'Electronics', 599.99),  
('Book', 'Books', 29.99),  
('Coffee Mug', 'Kitchenware', 12.99),  
('T-Shirt', 'Clothing', 34.99);

销售记录表 sales

CREATE TABLE sales (  sale_id INT AUTO_INCREMENT PRIMARY KEY,  product_id INT,  quantity INT NOT NULL,  sale_date DATE NOT NULL,  FOREIGN KEY (product_id) REFERENCES products(product_id)  
);  INSERT INTO sales (product_id, quantity, sale_date) VALUES  
(1, 2, '2023-04-01'),  
(2, 5, '2023-04-02'),  
(3, 3, '2023-04-01'),  
(4, 1, '2023-04-03'),  
(1, 1, '2023-04-04');

题目一:查询每个商品类别的商品数量。

答案:

SELECT category, COUNT(*) AS product_count  
FROM products  
GROUP BY category;

解析:

通过GROUP BY子句按category字段分组,并使用COUNT(*)函数计算每个类别的商品数量。

题目二:查询2023年4月份销售数量最多的商品名称及其销售数量。

答案:

SELECT p.name, SUM(s.quantity) AS total_quantity  
FROM sales s  
JOIN products p ON s.product_id = p.product_id  
WHERE YEAR(s.sale_date) = 2023 AND MONTH(s.sale_date) = 4  
GROUP BY p.product_id, p.name  
ORDER BY total_quantity DESC  
LIMIT 1;

解析:

首先通过连接sales和products表获取销售记录的商品信息,然后使用WHERE子句筛选出2023年4月份的销售记录。接着按商品分组并计算销售数量,最后通过ORDER BY和LIMIT子句找出销售数量最多的商品。

题目三:查询没有销售记录的商品。

答案:

SELECT * FROM products  
WHERE product_id NOT IN (SELECT DISTINCT product_id FROM sales);

或者

SELECT p.*  
FROM products p  
LEFT JOIN sales s ON p.product_id = s.product_id  
WHERE s.sale_id IS NULL;

解析:

第一种方法使用子查询找出有销售记录的商品ID,然后在主查询中排除这些ID。第二种方法通过左连接products和sales表,并检查sales.sale_id是否为NULL来找出没有销售记录的商品。

题目四:查询每个商品的销售总额,并按销售总额降序排列。

答案:

SELECT p.name, SUM(s.quantity * p.price) AS total_sales  
FROM sales s  
JOIN products p ON s.product_id = p.product_id  
GROUP BY p.product_id, p.name  
ORDER BY total_sales DESC;

解析:

通过连接sales和products表,计算每个商品的销售总额(数量乘以单价),然后按销售总额降序排列。

案例3(Mysql 8.0+版本)

建表语句与模拟数据

员工表 employees

CREATE TABLE employees (  employee_id INT AUTO_INCREMENT PRIMARY KEY,  name VARCHAR(100) NOT NULL,  department_id INT,  salary DECIMAL(10, 2) NOT NULL,  hire_date DATE NOT NULL,  FOREIGN KEY (department_id) REFERENCES departments(department_id)  
);  INSERT INTO employees (name, department_id, salary, hire_date) VALUES  
('John Doe', 1, 70000.00, '2020-01-01'),  
('Jane Smith', 2, 65000.00, '2020-02-15'),  
('Alice Johnson', 1, 68000.00, '2020-03-01'),  
('Bob Brown', 3, 85000.00, '2019-12-15'),  
('Charlie Davis', 2, 62000.00, '2020-01-10');

部门表 departments

CREATE TABLE departments (  department_id INT AUTO_INCREMENT PRIMARY KEY,  name VARCHAR(100) NOT NULL  
);  INSERT INTO departments (name) VALUES  
('Engineering'),  
('Marketing'),  
('Finance');

项目表 projects

CREATE TABLE projects (  project_id INT AUTO_INCREMENT PRIMARY KEY,  name VARCHAR(100) NOT NULL,  manager_id INT,  FOREIGN KEY (manager_id) REFERENCES employees(employee_id)  
);  INSERT INTO projects (name, manager_id) VALUES  
('Project X', 1),  
('Project Y', 2),  
('Project Z', 3);

题目一:查询每个部门薪资最高的员工信息(包括员工姓名、部门名称和薪资)。

答案:

(使用子查询):
SELECT e.name, d.name AS department_name, e.salary  
FROM employees e  
JOIN departments d ON e.department_id = d.department_id  
WHERE (e.department_id, e.salary) IN (  SELECT department_id, MAX(salary)  FROM employees  GROUP BY department_id  
);

注意:上述查询在某些数据库系统中可能无法直接工作,因为它依赖于子查询返回的结果集与主查询中的多个列进行匹配。在MySQL中,更稳妥的方法是使用窗口函数(如果可用)或进行更复杂的自连接。

使用窗口函数的版本(MySQL 8.0+)
WITH RankedEmployees AS (  SELECT e.name, d.name AS department_name, e.salary,  RANK() OVER (PARTITION BY e.department_id ORDER BY e.salary DESC) AS rank  FROM employees e  JOIN departments d ON e.department_id = d.department_id  
)  
SELECT name, department_name, salary  
FROM RankedEmployees  
WHERE rank = 1;

题目二:查询每个项目及其经理的姓名,以及该经理所在部门的名称。

答案:

SELECT p.name AS project_name, e.name AS manager_name, d.name AS department_name  
FROM projects p  
JOIN employees e ON p.manager_id = e.employee_id  
JOIN departments d ON e.department_id = d.department_id;

题目三:查询每个部门的平均薪资,以及该部门薪资高于公司平均薪资的员工数量。

答案:

WITH AvgSalary AS (  SELECT AVG(salary) AS company_avg_salary  FROM employees  
),  
DeptAvg AS (  SELECT department_id, AVG(salary) AS dept_avg_salary  FROM employees  GROUP BY department_id  
),  
DeptDetails AS (  SELECT d.name AS department_name,  da.dept_avg_salary,  as1.company_avg_salary,  COUNT(*) FILTER (WHERE e.salary > as1.company_avg_salary) AS above_avg_count  FROM departments d  JOIN DeptAvg da ON d.department_id = da.department_id  JOIN AvgSalary as1  JOIN employees e ON d.department_id = e.department_id  GROUP BY d.department_id, da.dept_avg_salary, as1.company_avg_salary  
)  
SELECT * FROM DeptDetails;

注意:这个查询使用了CTE(公用表表达式)来组织子查询,并通过FILTER子句计算薪资高于公司平均薪资的员工数量。不过,请注意,MySQL直到8.0版本才支持FILTER子句,如果版本较低,可能需要使用CASE语句代替。

题目四:查询入职时间最早的员工信息,以及他/她管理的项目名称(如果有的话)。

答案

SELECT e.name, p.name AS project_name  
FROM employees e  
LEFT JOIN projects p ON e.employee_id = p.manager_id  
WHERE e.hire_date = (  SELECT MIN(hire_date) FROM employees  
)  
ORDER BY p.project_id;  -- 如果有多个最早入职的员工且他们管理的项目不同,则按项目ID排序

案例4

建表语句与模拟数据

用户表 (users)

CREATE TABLE users (  id INT AUTO_INCREMENT PRIMARY KEY,  username VARCHAR(50) NOT NULL UNIQUE,  email VARCHAR(100) NOT NULL UNIQUE,  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP  
);  INSERT INTO users (username, email) VALUES  
('alice', 'alice@example.com'),  
('bob', 'bob@example.com'),  
('charlie', 'charlie@example.com');

订单表 (orders)

CREATE TABLE orders (  id INT AUTO_INCREMENT PRIMARY KEY,  user_id INT,  product_name VARCHAR(100),  quantity INT,  order_date DATE,  FOREIGN KEY (user_id) REFERENCES users(id)  
);  INSERT INTO orders (user_id, product_name, quantity, order_date) VALUES  
(1, 'Laptop', 1, '2023-04-01'),  
(2, 'Smartphone', 2, '2023-04-02'),  
(1, 'Tablet', 1, '2023-04-03'),  
(3, 'Headphones', 1, '2023-04-04');

题目一: 查询每个用户的用户名、电子邮件以及他们订购的商品总数。

答案:

SELECT u.username, u.email, COUNT(o.id) AS total_orders  
FROM users u  
LEFT JOIN orders o ON u.id = o.user_id  
GROUP BY u.id;

解析:

我们使用了LEFT JOIN来连接users表和orders表,确保即使某些用户没有订单也能被包含在结果中。
使用COUNT(o.id)来计算每个用户的订单总数。
通过GROUP BY u.id来按用户分组,以便为每个用户聚合订单数量。

题目二: 查询在2023年4月2日之后下单的用户,包括用户名和订单日期。

答案:

SELECT u.username, o.order_date  
FROM users u  
JOIN orders o ON u.id = o.user_id  
WHERE o.order_date > '2023-04-02';

解析:

我们使用了INNER JOIN来连接users表和orders表,因为我们只关心有订单的用户。
使用WHERE子句来过滤出订单日期在2023年4月2日之后的记录。
选择username和order_date作为输出列。

题目三: 查询订单总数最多的用户及其订单总数。

答案:

SELECT u.username, COUNT(o.id) AS total_orders  
FROM users u  
JOIN orders o ON u.id = o.user_id  
GROUP BY u.id  
ORDER BY total_orders DESC  
LIMIT 1;

解析:

类似于第一个问题,我们使用了JOIN和GROUP BY来按用户分组并计算订单总数。
通过ORDER BY total_orders DESC将结果按订单总数降序排列。
使用LIMIT 1来获取订单总数最多的用户。

案例5

建表语句与模拟数据

用户表 (users)

CREATE TABLE users (  id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',  username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',  email VARCHAR(100) NOT NULL UNIQUE COMMENT '电子邮件'  
);  INSERT INTO users (username, email) VALUES  
('alice', 'alice@example.com'),  
('bob', 'bob@example.com'),  
('charlie', 'charlie@example.com');

订单表 (orders)

CREATE TABLE orders (  id INT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',  user_id INT NOT NULL COMMENT '用户ID',  product_name VARCHAR(100) NOT NULL COMMENT '产品名称',  quantity INT NOT NULL COMMENT '数量',  order_date DATE NOT NULL COMMENT '订单日期',  FOREIGN KEY (user_id) REFERENCES users(id)  
);  INSERT INTO orders (user_id, product_name, quantity, order_date) VALUES  
(1, 'Laptop', 1, '2023-04-01'),  
(2, 'Smartphone', 2, '2023-04-02'),  
(1, 'Tablet', 1, '2023-04-03'),  
(3, 'Headphones', 1, '2023-04-04'),  
(2, 'Smartphone', 1, '2023-04-05');

题目一: 查询每个用户的用户名及其订单总数。

解题思路:

  • 使用JOIN连接users和orders表。
  • 使用GROUP BY按用户分组。
  • 使用COUNT聚合函数计算每个用户的订单总数。

答案:

SELECT u.username, COUNT(o.id) AS total_orders  
FROM users u  
JOIN orders o ON u.id = o.user_id  
GROUP BY u.id, u.username;

解析:

  • JOIN用于连接用户表和订单表,以便获取每个用户的订单信息。
  • GROUP BY用于按用户分组,确保每个用户只出现一次在结果集中。
  • COUNT(o.id)计算每个用户组的订单总数。

题目二: 查询每个产品名称的总销售数量(即该产品被购买的总数量)。

解题思路:

  • 直接对orders表进行GROUP BY操作,按产品名称分组。
  • 使用SUM聚合函数计算每个产品组的销售数量总和。

答案:

SELECT product_name, SUM(quantity) AS total_sales  
FROM orders  
GROUP BY product_name;

解析:

  • GROUP BY按产品名称分组,确保每个产品只出现一次在结果集中。
  • SUM(quantity)计算每个产品组的销售数量总和。

题目3: 查询每个用户在2023年4月份下的订单数量及订单总金额

(假设每种产品的单价固定,Laptop为999.99, Smartphone为599.99, Tablet为399.99, Headphones为99.99)。

解题思路:

  • 使用JOIN连接users和orders表。
  • 使用WHERE子句过滤出2023年4月份的订单。
  • 使用CASE语句或临时表/子查询来确定每种产品的价格,并计算订单总金额。
  • 使用GROUP BY按用户分组,并使用COUNT和SUM进行聚合。

由于直接在SQL中处理动态价格可能稍显复杂,这里简化处理,假设价格已知:

答案:

SELECT   u.username,   COUNT(o.id) AS order_count,  SUM(  CASE   WHEN o.product_name = 'Laptop' THEN o.quantity * 999.99  WHEN o.product_name = 'Smartphone' THEN o.quantity * 599.99  WHEN o.product_name = 'Tablet' THEN o.quantity * 399.99  WHEN o.product_name = 'Headphones' THEN o.quantity * 99.99  ELSE 0  END  ) AS total_amount  
FROM users u  
JOIN orders o ON u.id = o.user_id  
WHERE YEAR(o.order_date) = 2023 AND MONTH(o.order_date) = 4  
GROUP BY u.id, u.username;

解析:

  • JOIN和WHERE子句用于连接和过滤出2023年4月份的订单。
  • CASE语句用于根据产品名称确定单价,并计算每个订单的金额。
  • SUM聚合函数用于计算每个用户的订单总金额。
  • COUNT聚合函数用于计算每个用户的订单数量。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/426881.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『功能项目』QFrameWork框架重构OnGUI【63】

我们打开上一篇62QFrameWork背包框架的项目, 上文将功能实现在一个脚本中 本章要做的事情让脚本实现背包框架思想 首先按照图示创建脚本: 创建脚本:Item.cs namespace QFramework {public class Item{//道具public string Key;public string …

2024秋季云曦开学考

web ezezssrf 打开环境,代码审计 看起来有点多,要绕过五层 第一层:存在弱比较,使用数组或0e绕过 yunxi[]1&wlgf[]2 yunxis878926199a&wlgfs155964671a 第二层:存在强比较,此处使用string限制…

superset 解决在 mac 电脑上发送 slack 通知的问题

参考文档: https://superset.apache.org/docs/configuration/alerts-reports/ 核心配置: FROM apache/superset:3.1.0USER rootRUN apt-get update && \apt-get install --no-install-recommends -y firefox-esrENV GECKODRIVER_VERSION0.29.0 RUN wget -q https://g…

【智路】智路OS airos-edge

欢迎来到智路OS https://gitee.com/ZhiluCommunity/airos-edge 智路OS是全球首个开源开放的智能网联路侧单元操作系统(简称“智路OS”), 是以高等级自动驾驶技术为牵引,沉淀出来的“车路云网图”一体化的智能交通基础软件平台。…

Ansible——Playbook基本功能

文章目录 一、Ansible Playbook介绍1、Playbook的简单组成1)“play”2)“task”3)“playbook” 2、Playbook与ad-hoc简单对比区别联系 3、YAML文件语法:1. 基本结构2. 数据类型3. 列表4. 字典(映射)5. 注释…

【数据结构】排序算法---归并排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言——迭代版C语言——递归版PythonJavaC——迭代版C——递归版Go 结语 1. 定义 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法&#xff0…

CentOS7.9环境上NFS搭建及使用

Linux环境NFS搭建及使用 1. 服务器规划2. NFS服务器配置2.1 主机名设置2.2 nfs安装2.2.1 repo文件替换2.2.2 NFS服务安装 2.3 nfs配置2.4 服务查看2.5 资源发布2.6 配置nfs服务开机自启2.7 端口开放 3.应用服务器配置3.1 主机名设置3.2 nfs安装3.2.1 repo文件替换3.2.2 NFS服务…

你真的需要理解Diffusion(扩散模型),它在视觉领域具有无与伦比的美丽!

【Vision结合Diffusion】模型的研究方向,探索了如何利用扩散模型在数据空间中模拟随机游走的特性,以生成高质量和逼真的图像。这一领域的研究,通过结合视觉感知和文本描述,推动了图像合成技术的发展,尤其是在个性化图像…

对人像图添加指定光源,再进行二次扩图

在一些业务场景中,需要对人像图片添加特定光源,来增加氛围感,例如赛博朋克科技、海边夕阳余晖、以及红蓝相间的高冷;但实现这个功能的难点是:如何将光源与原图片融合,在图片上产生正常光的镜面反射&#xf…

从数据仓库到数据中台再到数据飞轮:我了解的数据技术进化史

这里写目录标题 前言数据仓库:数据整合的起点数据中台:数据共享的桥梁数据飞轮:业务与数据的双向驱动结语 前言 在当今这个数据驱动的时代,企业发展离不开对数据的深度挖掘和高效利用。从最初的数据仓库,到后来的数据…

工业一体机在汽车零部件工厂ESOP系统中的关键作用

在当今竞争激烈的汽车市场中,汽车零部件工厂的高效生产和严格质量控制至关重要。而工业一体机在汽车零部件工厂的 ESOP(电子标准化作业程序)系统中发挥着关键作用。 一、汽车零部件工厂面临的挑战 汽车零部件的生产过程复杂且要求严格&#…

【sgCreateCallAPIFunctionParam】自定义小工具:敏捷开发→调用接口方法参数生成工具

<template><div :class"$options.name" class"sgDevTool"><sgHead /><div class"sg-container"><div class"sg-start"><div style"margin-bottom: 10px">参数列表[逗号模式]<el-too…

soc及其相关概念

用户无法直接操作内存&#xff0c;只能让内存映射到用户空间然后操作 1. 内存映射&#xff08;Memory-Mapped Files&#xff09;内存映射文件是一种方法&#xff0c;它允许一个或多个进程将一个文件或者一个匿名区域映射到它们各自的虚拟地址空间中。当文件被映射到内存后&…

Android WebView H5 Hybrid 混和开发

对于故乡&#xff0c;我忽然有了新的理解&#xff1a;人的故乡&#xff0c;并不止于一块特定的土地&#xff0c;而是一种辽阔无比的心情&#xff0c;不受空间和时间的限制&#xff1b;这心情一经唤起&#xff0c;就是你已经回到了故乡。——《记忆与印象》 前言 移动互联网发展…

前端开发之迭代器模式

在前端开发中&#xff0c;设计模式是提升代码可读性、可扩展性和可维护性的关键。迭代器模式&#xff08;Iterator Pattern&#xff09;是行为型设计模式中的一种&#xff0c;能够让我们顺序访问一个集合中的元素&#xff0c;而不暴露其底层的结构。在 TypeScript 这样具有类型…

Golang | Leetcode Golang题解之第406题根据身高重建队列

题目&#xff1a; 题解&#xff1a; func reconstructQueue(people [][]int) (ans [][]int) {sort.Slice(people, func(i, j int) bool {a, b : people[i], people[j]return a[0] > b[0] || a[0] b[0] && a[1] < b[1]})for _, person : range people {idx : pe…

element-ui 日期选择器设置禁用日期

element-ui 日期选择器设置禁用日期 效果图如下&#xff1a; 2024-09-01 到2024-09-18之间的日期都不可选 2024-01-01之前的日期都不可选 官方文档中 picker-options 相关的介绍 实现功能&#xff1a; ​ 某仓库有限制最大可放置资产数量&#xff0c;且资产出借和存放都有…

高端论坛报告分享 | 李维森:中国地理信息产业发展报告(2024)

本报告为中国地理信息产业协会会长李维森在“2024中国地理信息产业大会”所作报告《中国地理信息产业发展报告&#xff08;2024&#xff09;》。转载请注明来源于中国地理信息产业协会。 本报告为中国地理信息产业协会会长李维森在“2024中国地理信息产业大会”所作报告《中国地…

Linux系统应用之知识补充——OpenEuler(欧拉)的安装和基础配置

前言 这篇文章将会对OpenEuler的安装进行详解&#xff0c;一步一步跟着走下去就可以成功 注意 &#xff1a;以下的指令操作最好在root权限下进行&#xff08;即su - root&#xff09; ☀️工贵其久&#xff0c;业贵其专&#xff01; 1、OpenEuler的安装 这里我不过多介绍&a…

GPT-4-Turbo 和 Claude-3.5-Sonnet 图片识别出答题的是否正确 进行比较

1、比较的图片&#xff1a; 使用GPT-4-Turbo 输入的 提问&#xff1a; 识别图片中的印刷字和手写字&#xff0c;如果写错的给一个正确答案 图片 回复&#xff1a; 在图片中&#xff0c;印刷字显示的是一系列的英语填空练习题&#xff0c;而手写字则是填入空白处的答案。以…