当前位置: 首页 > news >正文

Day11:关于MySQL的数据查询——子查询和联合查询

前言:先创建一个练习的数据库和数据

1.创建数据库并创建数据表的基本结构

-- 创建数据库
CREATE DATABASE subquery_union_simple;
USE subquery_union_simple;

-- 1. 员工表
CREATE TABLE employees (
    emp_id INT PRIMARY KEY AUTO_INCREMENT,
    emp_name VARCHAR(50) NOT NULL,
    salary DECIMAL(10,2) NOT NULL,
    hire_date DATE NOT NULL,
    dept VARCHAR(50) NOT NULL
);

-- 2. 客户表
CREATE TABLE customers (
    customer_id INT PRIMARY KEY AUTO_INCREMENT,
    customer_name VARCHAR(50) NOT NULL,
    city VARCHAR(50) NOT NULL,
    credit_rating VARCHAR(20) NOT NULL
);

-- 3. 订单表
CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT,
    emp_id INT,
    order_date DATE NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
    FOREIGN KEY (emp_id) REFERENCES employees(emp_id)
);

  2.导入实例数据 

-- 员工数据
INSERT INTO employees (emp_name, salary, hire_date, dept) VALUES
('张三', 8000.00, '2020-01-15', '销售部'),
('李四', 7500.00, '2021-03-20', '销售部'),
('王五', 9000.00, '2019-05-10', '技术部'),
('赵六', 8500.00, '2020-07-01', '技术部'),
('钱七', 7000.00, '2021-09-01', '财务部');

-- 客户数据
INSERT INTO customers (customer_name, city, credit_rating) VALUES
('客户A', '北京', '优秀'),
('客户B', '上海', '良好'),
('客户C', '广州', '一般'),
('客户D', '深圳', '优秀'),
('客户E', '杭州', '良好'),
('客户F', '成都', '一般');

-- 订单数据
INSERT INTO orders (customer_id, emp_id, order_date, amount) VALUES
(1, 1, '2023-01-05', 15000.00),
(2, 1, '2023-02-10', 8000.00),
(3, 2, '2023-03-15', 12000.00),
(1, 3, '2023-04-20', 25000.00),
(4, 4, '2023-05-25', 18000.00),
(5, 5, '2023-06-30', 30000.00),
(2, 1, '2023-07-05', 9000.00),
(6, NULL, '2023-08-10', 6000.00);  -- 未分配员工的订单

一、子查询(嵌套查询)

子查询的主要用途是在执行某个查询的过程中使用另一个查询的结果,即在WHERE子句中包含了另一个SELECT语句,这种将一个查询嵌套在另一个查询的WHERE子句中的查询称为子查询,也称为嵌套查询。

1.结果为单个值

子查询结果为单个值时,条件中可以使用“=”“>”“<”“<=”“>=”“!=”“<>”等比较运算符。

查询工资高于平均工资的员工

SELECT emp_name, salary 
FROM employees 
WHERE salary > AVG(salary);

mysql> SELECT emp_name, salary
    -> FROM employees
    -> WHERE salary > AVG(salary);
ERROR 1111 (HY000): Invalid use of group function

由于WHERE子句中不可以使用聚合函数

SELECT emp_name, salary 
FROM employees 
WHERE salary > (SELECT AVG(salary) FROM employees);

mysql> SELECT emp_name, salary
    -> FROM employees
    -> WHERE salary > (SELECT AVG(salary) FROM employees);
+----------+---------+
| emp_name | salary  |
+----------+---------+
| 王五     | 9000.00 |
| 赵六     | 8500.00 |
+----------+---------+
2 rows in set (0.05 sec)

2.结果为多个值的集合

子查询结果有多个值时,可以使用ANY、SOME、ALL、IN等运算符。

查询信用评级为"优秀"的客户的所有订单

SELECT * FROM orders 
WHERE customer_id IN (
    SELECT customer_id FROM customers 
    WHERE credit_rating = '优秀'
);


mysql> SELECT * FROM orders
    -> WHERE customer_id IN (
    ->     SELECT customer_id FROM customers
    ->     WHERE credit_rating = '优秀'
    -> );
+----------+-------------+--------+------------+----------+
| order_id | customer_id | emp_id | order_date | amount   |
+----------+-------------+--------+------------+----------+
|        1 |           1 |      1 | 2023-01-05 | 15000.00 |
|        4 |           1 |      3 | 2023-04-20 | 25000.00 |
|        5 |           4 |      4 | 2023-05-25 | 18000.00 |
+----------+-------------+--------+------------+----------+
3 rows in set (0.05 sec)

3.EXISTS子查询

EXISTS用于测试子查询的结果是否为空,如果结果不为空,则返回TRUE;否则返回FALSE。

查询有订单的客户

SELECT customer_name 
FROM customers c 
WHERE EXISTS (
    SELECT 1 FROM orders 
    WHERE customer_id = c.customer_id
);

mysql> SELECT customer_name
    -> FROM customers c
    -> WHERE EXISTS (
    ->     SELECT 1 FROM orders
    ->     WHERE customer_id = c.customer_id
    -> );
+---------------+
| customer_name |
+---------------+
| 客户A         |
| 客户B         |
| 客户C         |
| 客户D         |
| 客户E         |
| 客户F         |
+---------------+
6 rows in set (0.00 sec)

 二、联合查询

联合查询是将两个查询结果集合并为一个查询结果集,使用关键字UNION

SELECT 语句1
UNION  [ ALL | DISTINCT ]
SELECT 语句2;

1.UNION运算符可以将前后两个SELECT语句的查询结果进行合并,生成一个数据集。

2.联合查询时默认选项为DISTINCT,表示查询结果集中消除了重复行,所有的记录都是唯一的;若选项为ALL,表示查询结果集中包含查询出的所有记录行。

3.联合查询中的两个SELECT语句必须具有相同的字段列数目、且各字段列具有相同的数据类型。 

合并员工和客户名称

SELECT emp_name AS name, '员工' AS type FROM employees
UNION
SELECT customer_name, '客户' FROM customers;

mysql> SELECT emp_name AS name, '员工' AS type FROM employees
    -> UNION
    -> SELECT customer_name, '客户' FROM customers;
+-------+------+
| name  | type |
+-------+------+
| 张三  | 员工 |
| 李四  | 员工 |
| 王五  | 员工 |
| 赵六  | 员工 |
| 钱七  | 员工 |
| 客户A | 客户 |
| 客户B | 客户 |
| 客户C | 客户 |
| 客户D | 客户 |
| 客户E | 客户 |
| 客户F | 客户 |
+-------+------+
11 rows in set (0.05 sec)

合并所有城市信息(员工所在部门和客户所在城市)

SELECT dept AS location, '部门' AS type FROM employees
UNION ALL
SELECT city, '城市' FROM customers;

mysql> SELECT dept AS location, '部门' AS type FROM employees
    -> UNION ALL
    -> SELECT city, '城市' FROM customers;
+----------+------+
| location | type |
+----------+------+
| 销售部   | 部门 |
| 销售部   | 部门 |
| 技术部   | 部门 |
| 技术部   | 部门 |
| 财务部   | 部门 |
| 北京     | 城市 |
| 上海     | 城市 |
| 广州     | 城市 |
| 深圳     | 城市 |
| 杭州     | 城市 |
| 成都     | 城市 |
+----------+------+
11 rows in set (0.00 sec)

创建销售活动报表(联合查询)

将销售部门的员工薪资数据与销售部门处理的订单金额数据合并成一个结果集,

并按类别和数值降序排列。

查询分为两部分:

第一部分从员工表选取销售部门员工的ID、姓名、薪资,并标记为"员工薪资"类别;

第二部分通过关联订单、客户和员工表,获取销售部门员工处理的订单ID、客户名称、订单金额,并标记为"订单金额"类别。

UNION ALL操作符将这两个结果集合并而不去重,最终结果按类别分组,并在每个类别内按金额/薪资从高到低排序,便于比较销售部门员工的薪资水平和他们产生的订单业绩

SELECT 
    emp_id AS id, 
    emp_name AS name, 
    salary AS value, 
    '员工薪资' AS category
FROM employees
WHERE dept = '销售部'
UNION ALL
SELECT 
    o.order_id, 
    c.customer_name, 
    o.amount, 
    '订单金额'
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN employees e ON o.emp_id = e.emp_id
WHERE e.dept = '销售部'
ORDER BY category, value DESC;

mysql> SELECT
    ->     emp_id AS id,
    ->     emp_name AS name,
    ->     salary AS value,
    ->     '员工薪资' AS category
    -> FROM employees
    -> WHERE dept = '销售部'
    -> UNION ALL
    -> SELECT
    ->     o.order_id,
    ->     c.customer_name,
    ->     o.amount,
    ->     '订单金额'
    -> FROM orders o
    -> JOIN customers c ON o.customer_id = c.customer_id
    -> JOIN employees e ON o.emp_id = e.emp_id
    -> WHERE e.dept = '销售部'
    -> ORDER BY category, value DESC;
+----+-------+----------+----------+
| id | name  | value    | category |
+----+-------+----------+----------+
|  1 | 客户A | 15000.00 | 订单金额 |
|  3 | 客户C | 12000.00 | 订单金额 |
|  7 | 客户B |  9000.00 | 订单金额 |
|  2 | 客户B |  8000.00 | 订单金额 |
|  1 | 张三  |  8000.00 | 员工薪资 |
|  2 | 李四  |  7500.00 | 员工薪资 |
+----+-------+----------+----------+
6 rows in set (0.05 sec)

相关文章:

  • Python语言介绍
  • 代码随想录算法训练营day2(数组)
  • Docker安装常用软件教程(带完整命令)
  • 6.好事多磨 -- UDP网络连接
  • STP基本实验
  • 【C语言】预处理(下)(C语言完结篇)
  • 事件过滤器
  • MySQL 面经
  • 十七、TCP编程
  • 在 Lua 中实现 JSON 与 Table 的相互转换的详细使用方法
  • 《人件》第二章 办公环境
  • CLIP中的Zero-Shot Learning原理
  • `offset_mapping` 是什么
  • C语言—程序的编译和链接
  • 【项目管理】第11章 项目成本管理-- 知识点整理
  • JVM 字节码是如何存储信息的?
  • 开源项目Syncthing-Android环境搭建与编译
  • PostgreSQL内幕探索—基础知识
  • CesiumForUnreal 本地矢量文件的加载,支持 shp/geojson 等常用格式
  • leetcode 2787. Ways to Express an Integer as Sum of Powers
  • 建设网站要求和注意事项/自己有产品怎么网络销售
  • 国际网站设计/微信广告投放平台
  • 电脑关键字被限制 购物网站/谷歌排名规则
  • 沈阳做微信和网站的公司/网站竞价推广都有哪些
  • 网站建设经验交流材料/营销策划方案怎么写
  • 做娱乐网站彩票代理/百度广告投放代理商