DISTINCT 去重的是整行而非单列,JOIN 一对多时因关联字段差异导致"看似重复实则不同";应优先用 EXISTS/IN、GROUP BY 或 ROW_NUMBER() 精准控制去重逻辑。为什么 DISTINCT 加了还是有重复?不是 DISTINCT 不管用,而是它去重的是整行结果------只要任意一列值不同,就算"不重复"。多表 JOIN 后,一对多关系(比如一个订单对应多个商品)天然会把主表记录"撑开",此时哪怕你只选主表字段,数据库仍按连接后的中间结果去重,ORDER_ID 看似一样,但因关联的 ITEM_ID、QUANTITY 等字段参与了 JOIN,整行实际不同。实操建议:先确认重复根源:用 SELECT * 查看原始 JOIN 结果,观察哪几列在变如果只需要主表数据,优先考虑 EXISTS 或 IN 替代 JOIN,避免物理拼接DISTINCT 必须紧贴 SELECT,不能写成 SELECT DISTINCT a.* FROM ...(MySQL 8.0+ 支持,但多数旧版本报错)用 GROUP BY 替代 DISTINCT 更可控GROUP BY 明确指定按哪些列聚合,比 DISTINCT 更易预测行为,也方便后续加聚合函数(如统计子项数量)。但它要求所有 SELECT 中的非分组字段必须用聚合函数包裹,否则报错(SQL 标准严格模式下)。常见错误现象:SELECT order_id, customer_name, COUNT(*) FROM orders o JOIN items i ON o.id = i.order_id GROUP BY order_id ------ customer_name 未出现在 GROUP BY 且没聚合,MySQL 5.7+ 默认拒绝执行。实操建议:只选主表关键字段时,GROUP BY 列和 SELECT 列保持一致,例如 SELECT o.id, o.status FROM orders o JOIN ... GROUP BY o.id, o.status需要附带子表信息(如最新一条日志),改用窗口函数 ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY created_at DESC) 过滤注意 GROUP BY 性能:字段越多、数据量越大,临时表和排序开销越高LEFT JOIN + IS NULL 检查缺失关联时别误伤主表想查"没关联到子表的主表记录",常写 LEFT JOIN ... WHERE sub.id IS NULL。但如果子表有多条匹配记录,LEFT JOIN 仍会产生多行,再用 WHERE 过滤时逻辑没问题,但容易忽略:若子表本就允许空值或存在重复键,IS NULL 可能匹配出意料之外的行。使用场景:排查订单无支付记录、用户无头像等"缺失"类问题。 RedClaw 百度推出的手机端万能AI Agent助手
相关推荐
小二·10 分钟前
Redis 内存溢出(OOM)排查与恢复实战pqk6V6Vep11 分钟前
Redis 分布式锁进阶第一篇讲解giaz14n9X27 分钟前
Redis 分布式锁进阶第六十一篇是一个Bug33 分钟前
MongoDB:像搭积木一样存数据IT知识分享40 分钟前
从零开发在线简繁转换工具:OpenCC 实战、避坑经验与方案选型lunzi_08261 小时前
【学习笔记】《Python编程 从入门到实践》第8章:函数定义、参数传递与模块导入ULIi096kr1 小时前
MySQL解决Too many connections报错:连接数爆满排查、优化与永久解决方案杨运交1 小时前
[030][Web模块]Spring Boot 验证与 OpenAPI 集成实战:从校验规则到文档生成培培说证1 小时前
2026财务岗位如何快速提升自身能力努力攻坚操作系统1 小时前
编程语言编译运行机制对比:C / Java / Python