MySQL 数据库中左连接导致数据统计变多的题目及解决方法 ...

打印 上一主题 下一主题

主题 989|帖子 989|积分 2967

目录

内容
一、 左连接的基本概念
二、左连接导致数据统计变多的原因
三、 解决方法
方法一:确保连接条件唯一
方法二:使用子查询或聚合函数
方法三:使用 DISTINCT
四、示例
五、总结

内容

在使用数据库进行数据分析时,连接操纵(如左连接 LEFT JOIN)是常见的数据处置惩罚本领。然而,不当的连接操纵大概导致数据统计结果异常,比方数据量变多。本文将具体探究左连接导致数据统计变多的原因,并提供相应的解决方法。
一、 左连接的基本概念

左连接(LEFT JOIN)是一种 SQL 操纵,它返回左表中的全部记载,以及右表中满足连接条件的记载。假如右表中没有匹配的记载,则结果集中右表的字段将填充为 NULL。左连接的语法如下:
  1. SELECT *
  2. FROM table1
  3. LEFT JOIN table2
  4. ON table1.common_field = table2.common_field;
复制代码
二、左连接导致数据统计变多的原因

在使用左连接时,假如右表中存在多个匹配的记载,左表中的每一条记载将会被重复多次,从而导致数据统计结果变多。以下是一个具体的例子来说明这个题目。
假设我们有两个表 order_info 和 dept_order_info,表布局如下:
表 order_info:
order_id
reg_date
is_deleted
type
1
2024-12-24
0
1
2
2024-12-25
0
1
3
2024-12-31
0
1
表 dept_order_info:
order_id
flag
dept_id
1
0
101
1
0
102
2
0
101
3
0
101
3
0
102
执行以下左连接查询:
  1. SELECT
  2.     oi.reg_date,
  3.     COUNT(oi.order_id) AS order_count
  4. FROM order_info oi
  5. LEFT JOIN dept_order_info doi
  6.     ON oi.order_id = doi.order_id
  7.     AND doi.flag = 0
  8.     AND doi.dept_id <> 0
  9. WHERE 1=1
  10.     AND oi.reg_date BETWEEN '2024-12-24' AND '2024-12-31'
  11.     AND oi.is_deleted = 0
  12.     AND oi.type != 4
  13. GROUP BY oi.reg_date;
复制代码
查询结果如下:
reg_date
order_count
2024-12-24
2
2024-12-25
1
2024-12-31
2
从结果可以看出,2024-12-24 和 2024-12-31 的 order_count 数量变多了,这是因为 dept_order_info 表中存在多个 order_id 相同的记载,导致左表中的每一条记载被重复多次。
三、 解决方法

为了解决左连接导致数据统计变多的题目,可以采取以下几种方法:
方法一:确保连接条件唯一

确保右表中的连接字段是唯一的,或者在连接条件中添加其他唯一标识符来制止重复。比方:
  1. ALTER TABLE dept_order_info
  2. ADD UNIQUE KEY unique_order_id_dept_id (order_id, dept_id);
复制代码
方法二:使用子查询或聚合函数

在连接之前对右表进行聚合处置惩罚,确保每个 order_id 只有一条记载。比方:
  1. SELECT
  2.     oi.reg_date,
  3.     COUNT(oi.order_id) AS order_count
  4. FROM order_info oi
  5. LEFT JOIN (
  6.     SELECT order_id
  7.     FROM dept_order_info
  8.     WHERE flag = 0 AND dept_id <> 0
  9.     GROUP BY order_id
  10. ) doi
  11. ON oi.order_id = doi.order_id
  12. WHERE 1=1
  13.     AND oi.reg_date BETWEEN '2024-12-24' AND '2024-12-31'
  14.     AND oi.is_deleted = 0
  15.     AND oi.type != 4
  16. GROUP BY oi.reg_date;
复制代码
方法三:使用 DISTINCT

在 SELECT 语句中使用 DISTINCT 关键字往复除重复记载。但这种方法大概会导致某些聚合函数的结果不正确,因此必要谨慎使用。
  1. SELECT
  2.     oi.reg_date,
  3.     COUNT(DISTINCT oi.order_id) AS order_count
  4. FROM order_info oi
  5. LEFT JOIN dept_order_info doi
  6.     ON oi.order_id = doi.order_id
  7.     AND doi.flag = 0
  8.     AND doi.dept_id <> 0
  9. WHERE 1=1
  10.     AND oi.reg_date BETWEEN '2024-12-24' AND '2024-12-31'
  11.     AND oi.is_deleted = 0
  12.     AND oi.type != 4
  13. GROUP BY oi.reg_date;
复制代码
四、示例

以下是一个完备的示例,展示了如何使用子查询来制止左连接导致的数据统计变多题目:
  1. -- 创建示例表CREATE TABLE order_info (    order_id INT NOT NULL,    reg_date DATE NOT NULL,    is_deleted INT NOT NULL,    type INT NOT NULL);CREATE TABLE dept_order_info (    order_id INT NOT NULL,    flag INT NOT NULL,    dept_id INT NOT NULL);-- 插入示例数据INSERT INTO order_info (order_id, reg_date, is_deleted, type) VALUES(1, '2024-12-24', 0, 1),(2, '2024-12-25', 0, 1),(3, '2024-12-31', 0, 1);INSERT INTO dept_order_info (order_id, flag, dept_id) VALUES(1, 0, 101),(1, 0, 102),(2, 0, 101),(3, 0, 101),(3, 0, 102);-- 使用子查询制止数据统计变多SELECT
  2.     oi.reg_date,
  3.     COUNT(oi.order_id) AS order_count
  4. FROM order_info oi
  5. LEFT JOIN (
  6.     SELECT order_id
  7.     FROM dept_order_info
  8.     WHERE flag = 0 AND dept_id <> 0
  9.     GROUP BY order_id
  10. ) doi
  11. ON oi.order_id = doi.order_id
  12. WHERE 1=1
  13.     AND oi.reg_date BETWEEN '2024-12-24' AND '2024-12-31'
  14.     AND oi.is_deleted = 0
  15.     AND oi.type != 4
  16. GROUP BY oi.reg_date;
复制代码
执行上述查询后,结果如下:
reg_date
order_count
2024-12-24
1
2024-12-25
1
2024-12-31
1
通过使用子查询,成功制止了数据统计变多的题目。
五、总结

左连接在数据处置惩罚中非常有用,但不当的连接操纵大概导致数据统计结果异常。通过确保连接条件唯一、使用子查询或聚合函数、以及谨慎使用 DISTINCT 关键字,可以有用解决左连接导致的数据统计变多题目。在实际操纵中,建议先备份数据,然后在低峰时段执行这些操纵,以确保数据的安全性和一致性。
希望本文能帮助你更好地明白和解决左连接导致的数据统计题目。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表