【MySQL】多表连接查询

在这里插入图片描述

个人主页:Guiat
归属专栏:MySQL

在这里插入图片描述

文章目录

  • 1. 多表连接查询概述
    • 1.1 连接查询的作用
    • 1.2 MySQL支持的连接类型
  • 2. 内连接 (INNER JOIN)
    • 2.1 内连接的特点
    • 2.2 内连接语法
    • 2.3 内连接实例
    • 2.4 多表内连接
  • 3. 左外连接 (LEFT JOIN)
    • 3.1 左外连接的特点
    • 3.2 左外连接语法
    • 3.3 左外连接实例
    • 3.4 多表左外连接
  • 4. 右外连接 (RIGHT JOIN)
    • 4.1 右外连接的特点
    • 4.2 右外连接语法
    • 4.3 右外连接实例
    • 4.4 多表右外连接
  • 5. 全外连接 (FULL JOIN)
    • 5.1 全外连接的特点
    • 5.2 模拟全外连接语法
    • 5.3 模拟全外连接实例
    • 5.4 多表模拟全外连接
  • 6. 交叉连接 (CROSS JOIN)
    • 6.1 交叉连接的特点
    • 6.2 交叉连接语法
    • 6.3 交叉连接实例
    • 6.4 交叉连接应用场景
  • 7. 自连接 (Self Join)
    • 7.1 自连接的特点
    • 7.2 自连接语法
    • 7.3 自连接实例
    • 7.4 层次结构查询
  • 8. 高级连接技术
    • 8.1 USING 子句
    • 8.2 NATURAL JOIN
    • 8.3 连接条件与过滤条件
    • 8.4 子查询与连接
    • 8.5 STRAIGHT_JOIN
  • 9. 连接优化技术
    • 9.1 使用EXPLAIN分析连接查询
    • 9.2 索引优化
    • 9.3 查询重写技术
    • 9.4 分页优化
  • 10. 实际应用案例
    • 10.1 销售报表查询
    • 10.2 库存管理查询

正文

1. 多表连接查询概述

多表连接查询是关系型数据库中最重要的特性之一,它允许我们从多个相关表中检索数据,将它们按照指定的关系组合在一起显示。MySQL支持多种连接类型,使开发者能够灵活地进行数据检索和分析。

1.1 连接查询的作用

  • 整合分散在不同表中的相关数据
  • 减少数据冗余,提高存储效率
  • 支持复杂的业务逻辑和数据分析
  • 实现数据的完整性和一致性

1.2 MySQL支持的连接类型

MySQL支持以下几种主要的表连接类型:

MySQL连接类型
内连接 INNER JOIN
左外连接 LEFT JOIN
右外连接 RIGHT JOIN
全外连接 模拟实现
交叉连接 CROSS JOIN
自连接 Self Join

2. 内连接 (INNER JOIN)

2.1 内连接的特点

  • 只返回两个表中匹配的记录
  • 不包含任何不匹配的记录
  • 是最常用的连接类型
  • 可以使用关键字INNER JOIN或简写为JOIN

2.2 内连接语法

SELECT columns
FROM table1
INNER JOIN table2 ON table1.column = table2.column;-- 或使用简写形式
SELECT columns
FROM table1
JOIN table2 ON table1.column = table2.column;

2.3 内连接实例

-- 创建示例表
CREATE TABLE customers (customer_id INT PRIMARY KEY,customer_name VARCHAR(100) NOT NULL,email VARCHAR(100),phone VARCHAR(20)
);CREATE TABLE orders (order_id INT PRIMARY KEY,customer_id INT,order_date DATE NOT NULL,total_amount DECIMAL(10, 2) NOT NULL,FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);-- 基本内连接查询
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date, o.total_amount
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id;-- 多条件内连接
SELECT c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id AND o.total_amount > 1000;-- 使用WHERE子句进一步过滤
SELECT c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_date >= '2023-01-01' AND c.customer_name LIKE 'A%';

2.4 多表内连接

-- 创建额外示例表
CREATE TABLE order_items (item_id INT PRIMARY KEY,order_id INT,product_id INT,quantity INT NOT NULL,unit_price DECIMAL(10, 2) NOT NULL,FOREIGN KEY (order_id) REFERENCES orders(order_id)
);CREATE TABLE products (product_id INT PRIMARY KEY,product_name VARCHAR(100) NOT NULL,category VARCHAR(50),description TEXT
);-- 三表内连接
SELECT c.customer_name, o.order_id, o.order_date, p.product_name, oi.quantity, oi.unit_price, (oi.quantity * oi.unit_price) AS line_total
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
ORDER BY o.order_date, o.order_id;-- 四表及以上连接
SELECT c.customer_name, o.order_id, p.product_name, oi.quantity, s.company_name AS supplier
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
JOIN suppliers s ON p.supplier_id = s.supplier_id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31';

3. 左外连接 (LEFT JOIN)

3.1 左外连接的特点

  • 返回左表中的所有记录,无论是否匹配
  • 如果右表中没有匹配项,则显示为NULL
  • 用于查找主表中的所有记录及其关联信息
  • 也称为LEFT OUTER JOIN

3.2 左外连接语法

SELECT columns
FROM table1
LEFT JOIN table2 ON table1.column = table2.column;-- 完整形式
SELECT columns
FROM table1
LEFT OUTER JOIN table2 ON table1.column = table2.column;

3.3 左外连接实例

-- 基本左连接:查找所有客户及其订单(包括没有订单的客户)
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
ORDER BY c.customer_id;-- 查找没有订单的客户
SELECT c.customer_id, c.customer_name, c.email
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_id IS NULL;-- 带聚合函数的左连接
SELECT c.customer_id, c.customer_name, COUNT(o.order_id) AS order_count,IFNULL(SUM(o.total_amount), 0) AS total_spent
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.customer_name
ORDER BY total_spent DESC;

3.4 多表左外连接

-- 多表左外连接示例
SELECT c.customer_name, o.order_id, o.order_date, p.product_name, oi.quantity
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
LEFT JOIN order_items oi ON o.order_id = oi.order_id
LEFT JOIN products p ON oi.product_id = p.product_id
ORDER BY c.customer_name, o.order_date;-- 查找特定分类下的产品以及相关订单信息(包括未售出的产品)
SELECT p.product_id, p.product_name, p.category,o.order_id, c.customer_name, oi.quantity
FROM products p
LEFT JOIN order_items oi ON p.product_id = oi.product_id
LEFT JOIN orders o ON oi.order_id = o.order_id
LEFT JOIN customers c ON o.customer_id = c.customer_id
WHERE p.category = 'Electronics'
ORDER BY p.product_name;

4. 右外连接 (RIGHT JOIN)

4.1 右外连接的特点

  • 返回右表中的所有记录,无论是否匹配
  • 如果左表中没有匹配项,则显示为NULL
  • 功能上与左连接类似,只是表的方向相反
  • 也称为RIGHT OUTER JOIN

4.2 右外连接语法

SELECT columns
FROM table1
RIGHT JOIN table2 ON table1.column = table2.column;-- 完整形式
SELECT columns
FROM table1
RIGHT OUTER JOIN table2 ON table1.column = table2.column;

4.3 右外连接实例

-- 基本右连接:查找所有订单及其客户信息(包括没有客户信息的订单)
SELECT o.order_id, o.order_date, o.total_amount, c.customer_id, c.customer_name
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
ORDER BY o.order_id;-- 查找没有客户信息的订单(例如已删除的客户)
SELECT o.order_id, o.order_date, o.total_amount
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
WHERE c.customer_id IS NULL;-- 注意:右连接通常可以转换为左连接
-- 下面两个查询是等价的
SELECT c.customer_name, o.order_id, o.order_date
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id;SELECT c.customer_name, o.order_id, o.order_date
FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id;

4.4 多表右外连接

-- 多表右外连接示例
SELECT p.product_name, oi.quantity, o.order_id, c.customer_name
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
RIGHT JOIN order_items oi ON o.order_id = oi.order_id
RIGHT JOIN products p ON oi.product_id = p.product_id
ORDER BY p.product_name;-- 查找所有产品及其订单情况(包括未被订购的产品)
SELECT p.product_id, p.product_name, p.category,oi.order_id, oi.quantity, o.order_date
FROM order_items oi
RIGHT JOIN products p ON oi.product_id = p.product_id
LEFT JOIN orders o ON oi.order_id = o.order_id
ORDER BY p.product_id;

5. 全外连接 (FULL JOIN)

5.1 全外连接的特点

  • 返回左表和右表中的所有记录
  • 如果任一表中没有匹配项,则显示为NULL
  • MySQL不直接支持FULL JOIN语法
  • 可以通过UNION组合LEFT JOIN和RIGHT JOIN模拟

5.2 模拟全外连接语法

-- MySQL中模拟全外连接
SELECT columns
FROM table1
LEFT JOIN table2 ON table1.column = table2.column
UNION
SELECT columns
FROM table1
RIGHT JOIN table2 ON table1.column = table2.column
WHERE table1.column IS NULL;

5.3 模拟全外连接实例

-- 模拟全外连接:查找所有客户和订单(包括没有订单的客户和没有客户信息的订单)
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
UNION
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
WHERE c.customer_id IS NULL;-- 查找不匹配的记录(只存在于一个表中的记录)
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_id IS NULL
UNION
SELECT c.customer_id, c.customer_name, o.order_id, o.order_date
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id
WHERE c.customer_id IS NULL;

5.4 多表模拟全外连接

-- 多表模拟全外连接示例(产品和订单)
SELECT p.product_id, p.product_name, oi.order_id, oi.quantity
FROM products p
LEFT JOIN order_items oi ON p.product_id = oi.product_id
UNION
SELECT p.product_id, p.product_name, oi.order_id, oi.quantity
FROM products p
RIGHT JOIN order_items oi ON p.product_id = oi.product_id
WHERE p.product_id IS NULL;

6. 交叉连接 (CROSS JOIN)

6.1 交叉连接的特点

  • 返回两个表的笛卡尔积(所有可能的组合)
  • 每一行都与另一个表的每一行组合
  • 结果集行数 = 第一个表行数 × 第二个表行数
  • 通常需要加条件限制,否则结果集可能非常大

6.2 交叉连接语法

-- 使用CROSS JOIN关键字
SELECT columns
FROM table1
CROSS JOIN table2;-- 使用逗号分隔表(隐式交叉连接)
SELECT columns
FROM table1, table2;

6.3 交叉连接实例

-- 基本交叉连接:生成所有产品与类别的组合
CREATE TABLE categories (category_id INT PRIMARY KEY,category_name VARCHAR(50) NOT NULL
);-- 显式交叉连接
SELECT p.product_id, p.product_name, c.category_id, c.category_name
FROM products p
CROSS JOIN categories c;-- 隐式交叉连接(不推荐,因为容易与内连接混淆)
SELECT p.product_id, p.product_name, c.category_id, c.category_name
FROM products p, categories c;-- 有条件的交叉连接
SELECT p.product_id, p.product_name, c.category_name
FROM products p
CROSS JOIN categories c
WHERE p.product_id < 100 AND c.category_id IN (1, 2, 3);

6.4 交叉连接应用场景

-- 生成日期范围内的所有日期
CREATE TABLE numbers (n INT PRIMARY KEY);
INSERT INTO numbers VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);SELECT DATE_ADD('2023-01-01', INTERVAL (n1.n + n10.n*10 + n100.n*100) DAY) AS date
FROM numbers n1
CROSS JOIN numbers n10
CROSS JOIN numbers n100
WHERE DATE_ADD('2023-01-01', INTERVAL (n1.n + n10.n*10 + n100.n*100) DAY) <= '2023-12-31'
ORDER BY date;-- 创建价格矩阵
SELECT p1.product_name AS product, p2.product_name AS compared_with,p1.price AS price, p2.price AS compared_price,ROUND((p1.price - p2.price), 2) AS price_difference
FROM products p1
CROSS JOIN products p2
WHERE p1.product_id <> p2.product_id
ORDER BY p1.product_name, price_difference DESC;

7. 自连接 (Self Join)

7.1 自连接的特点

  • 表与自身进行连接
  • 在同一个表中查找相关记录
  • 通常用于处理层次结构或递归关系
  • 需要为表指定不同的别名

7.2 自连接语法

-- 自连接基本语法
SELECT a.column, b.column
FROM table a
JOIN table b ON a.column = b.another_column;

7.3 自连接实例

-- 创建示例员工表(含管理者关系)
CREATE TABLE employees (employee_id INT PRIMARY KEY,employee_name VARCHAR(100) NOT NULL,manager_id INT,department VARCHAR(50),salary DECIMAL(10, 2),FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);-- 查找每个员工及其直接经理
SELECT e.employee_id, e.employee_name, e.department,m.employee_id AS manager_id, m.employee_name AS manager_name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id
ORDER BY e.department, e.employee_id;-- 查找同一部门的员工
SELECT e1.employee_name AS employee1, e2.employee_name AS employee2,e1.department
FROM employees e1
JOIN employees e2 ON e1.department = e2.department
WHERE e1.employee_id < e2.employee_id  -- 避免重复组合
ORDER BY e1.department, e1.employee_name;-- 查找薪资比经理高的员工
SELECT e.employee_name AS employee, e.salary AS employee_salary,m.employee_name AS manager, m.salary AS manager_salary
FROM employees e
JOIN employees m ON e.manager_id = m.employee_id
WHERE e.salary > m.salary;

7.4 层次结构查询

-- 创建示例类别表(树形结构)
CREATE TABLE categories (category_id INT PRIMARY KEY,category_name VARCHAR(50) NOT NULL,parent_id INT,FOREIGN KEY (parent_id) REFERENCES categories(category_id)
);-- 查找直接子类别
SELECT p.category_id AS parent_id, p.category_name AS parent_category,c.category_id AS child_id, c.category_name AS child_category
FROM categories p
LEFT JOIN categories c ON p.category_id = c.parent_id
ORDER BY p.category_name, c.category_name;-- 使用递归CTE查询完整层次结构(MySQL 8.0+)
WITH RECURSIVE category_tree AS (-- 起始点:顶级类别SELECT category_id, category_name, parent_id, 0 AS level,category_name AS pathFROM categoriesWHERE parent_id IS NULLUNION ALL-- 递归部分:查找子类别SELECT c.category_id, c.category_name, c.parent_id, ct.level + 1,CONCAT(ct.path, ' > ', c.category_name)FROM categories cJOIN category_tree ct ON c.parent_id = ct.category_id
)
SELECT level, category_id, category_name, path
FROM category_tree
ORDER BY path;

8. 高级连接技术

8.1 USING 子句

当连接列具有相同的名称时,可以使用USING子句简化JOIN语法:

-- 使用ON子句的连接
SELECT c.customer_id, c.customer_name, o.order_date
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id;-- 使用USING子句的连接(更简洁)
SELECT customer_id, c.customer_name, o.order_date
FROM customers c
JOIN orders o USING (customer_id);-- USING子句处理多个相同列名
SELECT order_id, product_id, c.customer_name, p.product_name
FROM orders o
JOIN order_items oi USING (order_id)
JOIN customers c USING (customer_id)
JOIN products p USING (product_id);

8.2 NATURAL JOIN

NATURAL JOIN自动基于两个表中所有同名列进行连接:

-- 自然连接示例
SELECT customer_id, customer_name, order_id, order_date
FROM customers
NATURAL JOIN orders;-- 注意:自然连接可能导致意外结果,谨慎使用
-- 如果表有多个同名列,所有这些列都会被用于连接条件

8.3 连接条件与过滤条件

理解JOIN条件和WHERE条件的区别:

-- JOIN条件决定哪些行被连接
SELECT c.customer_name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id AND o.total_amount > 1000;-- WHERE条件在连接后过滤结果
SELECT c.customer_name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.total_amount > 1000;-- 这两个查询的结果不同:
-- 第一个查询会保留所有客户,即使他们没有订单或订单金额不超过1000
-- 第二个查询只保留有订单且订单金额超过1000的客户

8.4 子查询与连接

在某些情况下,子查询可以替代连接:

-- 使用连接查询高价值客户的最近订单
SELECT c.customer_name, o.order_id, o.order_date, o.total_amount
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE c.customer_id IN (SELECT customer_idFROM ordersGROUP BY customer_idHAVING SUM(total_amount) > 10000
)
AND o.order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY);-- 使用相关子查询查找每个客户的最近订单
SELECT c.customer_id, c.customer_name, (SELECT order_id FROM orders WHERE customer_id = c.customer_id ORDER BY order_date DESC LIMIT 1) AS latest_order_id,(SELECT order_date FROM orders WHERE customer_id = c.customer_id ORDER BY order_date DESC LIMIT 1) AS latest_order_date
FROM customers c;

8.5 STRAIGHT_JOIN

在特定情况下,可以使用STRAIGHT_JOIN提示优化器使用指定的表连接顺序:

-- 强制连接顺序
SELECT c.customer_name, o.order_id, oi.product_id
FROM customers STRAIGHT_JOIN orders o ON c.customer_id = o.customer_id
STRAIGHT_JOIN order_items oi ON o.order_id = oi.order_id;

9. 连接优化技术

9.1 使用EXPLAIN分析连接查询

-- 使用EXPLAIN分析查询执行计划
EXPLAIN SELECT c.customer_name, o.order_id, p.product_name, oi.quantity
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE c.customer_name LIKE 'A%' AND o.order_date > '2023-01-01';

9.2 索引优化

为连接列创建适当的索引可以显著提高JOIN性能:

-- 为连接列创建索引
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);-- 创建复合索引以优化特定查询
CREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);

9.3 查询重写技术

-- 拆分复杂连接为更简单的查询
-- 原复杂查询
SELECT c.customer_name, COUNT(DISTINCT o.order_id) AS order_count,SUM(oi.quantity * p.price) AS total_value
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY c.customer_id;-- 拆分为更简单的查询
-- 首先计算每个订单的价值
CREATE TEMPORARY TABLE order_values AS
SELECT o.order_id, o.customer_id, SUM(oi.quantity * p.price) AS order_value
FROM orders o
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY o.order_id, o.customer_id;-- 然后汇总客户数据
SELECT c.customer_name, COUNT(ov.order_id) AS order_count,SUM(ov.order_value) AS total_value
FROM customers c
JOIN order_values ov ON c.customer_id = ov.customer_id
GROUP BY c.customer_id;

9.4 分页优化

大结果集的分页查询可以通过优化连接顺序提高效率:

-- 普通分页查询(可能较慢)
SELECT c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
ORDER BY o.order_date DESC
LIMIT 1000, 50;-- 优化的分页查询
SELECT c.customer_name, o.order_id, o.order_date
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
ORDER BY o.order_date DESC
LIMIT 1000, 50;-- 进一步优化(先获取ID,再获取完整数据)
SELECT c.customer_name, o.order_id, o.order_date
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.order_id IN (SELECT order_idFROM ordersORDER BY order_date DESCLIMIT 1000, 50
);

10. 实际应用案例

10.1 销售报表查询

-- 按月份、产品类别和销售区域的销售报表
SELECT DATE_FORMAT(o.order_date, '%Y-%m') AS month,p.category,c.region,COUNT(DISTINCT o.order_id) AS order_count,COUNT(DISTINCT o.customer_id) AS customer_count,SUM(oi.quantity) AS total_quantity,SUM(oi.quantity * oi.unit_price) AS total_sales,AVG(oi.quantity * oi.unit_price) AS avg_order_value
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31'AND o.status != 'Cancelled'
GROUP BY DATE_FORMAT(o.order_date, '%Y-%m'), p.category, c.region
ORDER BY month, p.category, total_sales DESC;

10.2 库存管理查询

-- 库存周转分析
SELECT p.product_id,p.product_name,p.category,p.current_stock,IFNULL(SUM(oi.quantity), 0) AS total_sold,CASEWHEN p.current_stock > 0 AND SUM(oi.quantity) IS NOT NULL THEN ROUND(SUM(oi.quantity) / p.current_stock, 2)ELSE 0END AS turnover_ratio
FROM products p
LEFT JOIN order_items oi ON p.product_id = oi.product_id
LEFT JOIN orders o ON oi.order_id = o.order_id AND o.order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 90 DAY)
GROUP BY p.product_id, p.product_name, p.category, p.current_stock
ORDER BY turnover_ratio DESC;-- 需要补货的产品
SELECT p.product_id,p.product_name,p.current_stock,p.reorder_level,s.supplier_name,s.contact_person,s.phone
FROM products p
JOIN suppliers s ON p.supplier_id = s.supplier_id
LEFT JOIN (SELECT product_id, SUM(quantity) AS ordered_qtyFROM purchase_orders poJOIN purchase_order_items poi ON po.po_id = poi.po_idWHERE po.status = 'Pending'GROUP BY product_id
) pending ON p.product_id = pending.product_id
WHERE p.current_stock - IFNULL(pending.ordered_qty, 0) <= p.reorder_level
ORDER BY (p.current_stock - p.reorder_level);

结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

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

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

相关文章

养猪场巡检机器人的设计与应用研究

摘要 本论文针对传统养猪场人工巡检效率低、劳动强度大、数据准确性差等问题&#xff0c;设计了一种适用于养猪场的巡检机器人。详细阐述了该机器人的设计思路、技术原理、系统组成及功能特点&#xff0c;并通过实际应用案例分析其在养猪场中的应用效果。研究表明&#xff0c;养…

使用PEFT库将原始模型与LoRA权重合并

使用PEFT库将原始模型与LoRA权重合并 步骤如下&#xff1a; 基础模型加载&#xff1a;需保持与LoRA训练时相同的模型配置merge_and_unload()&#xff1a;该方法会执行权重合并并移除LoRA层保存格式&#xff1a;合并后的模型保存为标准HuggingFace格式&#xff0c;可直接用于推…

适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO

​一、软件介绍 文末提供程序和源码下载 该项目利用 Ultralytics 最先进的 YOLO11 模型将您的 iOS 设备转变为用于对象检测的强大实时推理工具。直接从 App Store 下载该应用程序&#xff0c;或浏览我们的指南&#xff0c;将 YOLO 功能集成到您自己的 Swift 应用程序中。 二、…

js关于number类型的计算问题

js中关于number类型的计算 因&#xff1a;在js中&#xff0c;number类型是用于表示数值的基本类型&#xff0c;它遵循 IEEE 754 双精度浮点数&#xff08;64 位&#xff09;标准。这导致在某些计算中可能出现精度问题。 例&#xff1a;console.log(0.1 0.2); // 0.300000000…

RAG之大规模解析 PDF 文档全流程实战

PDF 文档在商业、学术和政府领域无处不在,蕴含着大量宝贵信息。然而,从 PDF 中提取结构化数据却面临着独特的挑战,尤其是在处理数千甚至数百万个文档时。本指南探讨了大规模解析 PDF 的策略和工具。 PDF解析挑战 PDF 的设计初衷是为了提供一致的视觉呈现,而非数据提取。这…

TypeScript:类

一、基本概念 TypeScript 类是基于 ES6 类的语法扩展&#xff0c;增加了类型注解和访问修饰符等特性&#xff0c;提供了更强大的面向对象编程能力。 二、基本语法 class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.ag…

抢购Python代码示例与技术解析

引言&#xff1a;抢购系统的技术挑战 在当今电子商务高度发达的时代&#xff0c;抢购活动已成为各大电商平台吸引用户的重要手段。然而&#xff0c;高并发、低延迟的抢购场景对系统设计提出了严峻挑战。本文将提供一个完整的Python抢购代码示例&#xff0c;并深入分析其技术实…

实战分析Cpython逆向

Cpython逆向 Python代码转换为C代码的时候&#xff0c;将会大大增加框架代码量。 1、正向py->c 先有正向&#xff0c;再有逆向 pip install cython 写一个简单的pyx文件 .pyx 文件是由 Cython 编程语言 "编写" 而成的 Python 扩展模块源代码文件 print(&qu…

Modbus转IEC104网关(三格电子)

产品概述 Modbus转IE104网关型号SG-TCP-IEC104&#xff0c;是三格电子推出的工业级网关&#xff08;以下简称网关&#xff09;&#xff0c;主要用于Modbus RTU/TCP/ASCII数据采集、DLT645-1997/2007数据采集&#xff0c;可接多功能电力仪表、温控仪、电表等&#xff0c;将采集…

智能工具协同赋能STEM教育科研|探索LLM大语言模型和数学软件Maple的创新实践

LLM 与 Maple&#xff1a;开启 STEM 教育科研新范式 在当今数字化浪潮下&#xff0c;教育与科研领域正面临着前所未有的变革机遇。大语言模型&#xff08;LLM&#xff09;的横空出世&#xff0c;为知识生成、问题求解等带来了全新思路&#xff1b;而数学软件 Maple 以其强大的…

专项智能练习(定义判断)_DA_01

1. 单选题 热传导是介质内无宏观运动时的传热现象&#xff0c;其在固体、液体和气体中均可发生。但严格而言&#xff0c;只有在固体中才是纯粹的热传导&#xff0c;在流体&#xff08;泛指液体和气体&#xff09;中又是另外一种情况&#xff0c;流体即使处于静止状态&#xff0…

pandas读取pymysql和解析excel的一系列问题(版本不匹配)

pandas读取pymysql和解析excel的一系列问题&#xff0c;大部分都是版本不匹配导致的 尤其是pandas,numpy,pymysql,openpyxl不匹配导致 from sqlalchemy import create_engine import numpy as np import pandas as pd conncreate_engine("mysqlpymysql://user:passhost:3…

【中级软件设计师】网络攻击(附软考真题)

【中级软件设计师】网络攻击&#xff08;附软考真题&#xff09; 目录 【中级软件设计师】网络攻击&#xff08;附软考真题&#xff09;一、历年真题二、考点&#xff1a;网络攻击1、拒绝服务攻击&#xff08;DoS攻击&#xff09;2、重放攻击3、特洛伊木马4、网络监听5、SQL注入…

20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤

20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤 2025/5/15 19:55 百度&#xff1a;intel 集成显卡 NVIDIA 配置成为 总是用独立显卡 百度为您找到以下结果 ?要将Intel集成显卡和NVIDIA独立显卡配置为总是使用独立显卡&#xff0c;可以通过以下步骤实现?&#xff…

【C++ | 内存管理】C++ 智能指针 std::shared_ptr 详解及使用例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【CF】Day59——Codeforces Round 914 (Div. 2) D

D. Set To Max 题目&#xff1a; Easy 思路&#xff1a; 简单题 由于题目的数据给的很小&#xff0c;所以我们可以用 n 的复杂度过&#xff0c;那我们来观察一下我们应该怎么操作 显然&#xff0c;如果 a[i] > b[i] 时是无法构造的&#xff0c;同时 a[i] b[i] 时就不用管…

解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- GPT源代码解析

解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- GPT源代码解析 我们可以稍微看一下, 这是我们GPT的基于它的源代码产生的可视化的内容。 这边是model ,我们在谈这个sampling的时候,本身首先就是说它这个probability distribution ,会有很多的参数…

AI 推理 | vLLM 快速部署指南

本文是 AI 推理系列的第一篇&#xff0c;近期将更新与 vLLM 的相关内容。本篇从 vLLM 的部署开始&#xff0c;介绍 vLLM GPU/CPU 后端的安装方式&#xff0c;后续将陆续讲解 vLLM 的核心特性&#xff0c;如 PD 分离、Speculative Decoding、Prefix Caching 等&#xff0c;敬请关…

Python-MCPInspector调试

Python-MCPInspector调试 使用FastMCP开发MCPServer&#xff0c;熟悉【McpServer编码过程】【MCPInspector调试方法】-> 可以这样理解&#xff1a;只编写一个McpServer&#xff0c;然后使用MCPInspector作为McpClient进行McpServer的调试 1-核心知识点 1-熟悉【McpServer编…

Linux 常用命令 -hostnamectl【主机名控制】

简介 hostnamectl 命令中的 “hostname” 顾名思义&#xff0c;指的是计算机在网络上的名称&#xff0c;“ctl” 是 “control” 的缩写&#xff0c;意味着控制。hostnamectl 命令用于查询和修改系统主机名以及相关的设置。它通过与 systemd 系统管理器交互&#xff0c;允许用…